Upgrade to spring-javaformat 0.0.11

1.5.x
Andy Wilkinson 6 years ago
parent d548c5ed31
commit 8f1be4cded

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -82,8 +82,7 @@ public class AuditEvent implements Serializable {
* @param type the event type * @param type the event type
* @param data the event data * @param data the event data
*/ */
public AuditEvent(Date timestamp, String principal, String type, public AuditEvent(Date timestamp, String principal, String type, Map<String, Object> data) {
Map<String, Object> data) {
Assert.notNull(timestamp, "Timestamp must not be null"); Assert.notNull(timestamp, "Timestamp must not be null");
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
this.timestamp = timestamp; this.timestamp = timestamp;
@ -142,8 +141,8 @@ public class AuditEvent implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "AuditEvent [timestamp=" + this.timestamp + ", principal=" + this.principal return "AuditEvent [timestamp=" + this.timestamp + ", principal=" + this.principal + ", type=" + this.type
+ ", type=" + this.type + ", data=" + this.data + "]"; + ", data=" + this.data + "]";
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,8 +25,7 @@ import org.springframework.context.ApplicationListener;
* @author Vedran Pavic * @author Vedran Pavic
* @since 1.4.0 * @since 1.4.0
*/ */
public abstract class AbstractAuditListener public abstract class AbstractAuditListener implements ApplicationListener<AuditApplicationEvent> {
implements ApplicationListener<AuditApplicationEvent> {
@Override @Override
public void onApplicationEvent(AuditApplicationEvent event) { public void onApplicationEvent(AuditApplicationEvent event) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,8 +40,7 @@ public class AuditApplicationEvent extends ApplicationEvent {
* @param data the event data * @param data the event data
* @see AuditEvent#AuditEvent(String, String, Map) * @see AuditEvent#AuditEvent(String, String, Map)
*/ */
public AuditApplicationEvent(String principal, String type, public AuditApplicationEvent(String principal, String type, Map<String, Object> data) {
Map<String, Object> data) {
this(new AuditEvent(principal, type, data)); this(new AuditEvent(principal, type, data));
} }
@ -66,8 +65,7 @@ public class AuditApplicationEvent extends ApplicationEvent {
* @param data the event data * @param data the event data
* @see AuditEvent#AuditEvent(Date, String, String, Map) * @see AuditEvent#AuditEvent(Date, String, String, Map)
*/ */
public AuditApplicationEvent(Date timestamp, String principal, String type, public AuditApplicationEvent(Date timestamp, String principal, String type, Map<String, Object> data) {
Map<String, Object> data) {
this(new AuditEvent(timestamp, principal, type, data)); this(new AuditEvent(timestamp, principal, type, data));
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,8 +32,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
* @author Dave Syer * @author Dave Syer
*/ */
@Qualifier @Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@Documented @Documented

@ -43,8 +43,7 @@ public class AuditAutoConfiguration {
private final AuditEventRepository auditEventRepository; private final AuditEventRepository auditEventRepository;
public AuditAutoConfiguration( public AuditAutoConfiguration(ObjectProvider<AuditEventRepository> auditEventRepository) {
ObjectProvider<AuditEventRepository> auditEventRepository) {
this.auditEventRepository = auditEventRepository.getIfAvailable(); this.auditEventRepository = auditEventRepository.getIfAvailable();
} }
@ -55,16 +54,14 @@ public class AuditAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnClass( @ConditionalOnClass(name = "org.springframework.security.authentication.event.AbstractAuthenticationEvent")
name = "org.springframework.security.authentication.event.AbstractAuthenticationEvent")
@ConditionalOnMissingBean(AbstractAuthenticationAuditListener.class) @ConditionalOnMissingBean(AbstractAuthenticationAuditListener.class)
public AuthenticationAuditListener authenticationAuditListener() throws Exception { public AuthenticationAuditListener authenticationAuditListener() throws Exception {
return new AuthenticationAuditListener(); return new AuthenticationAuditListener();
} }
@Bean @Bean
@ConditionalOnClass( @ConditionalOnClass(name = "org.springframework.security.access.event.AbstractAuthorizationEvent")
name = "org.springframework.security.access.event.AbstractAuthorizationEvent")
@ConditionalOnMissingBean(AbstractAuthorizationAuditListener.class) @ConditionalOnMissingBean(AbstractAuthorizationAuditListener.class)
public AuthorizationAuditListener authorizationAuditListener() throws Exception { public AuthorizationAuditListener authorizationAuditListener() throws Exception {
return new AuthorizationAuditListener(); return new AuthorizationAuditListener();

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -152,8 +152,7 @@ public class CacheStatisticsAutoConfiguration {
public CacheStatisticsProvider<Cache> noOpCacheStatisticsProvider() { public CacheStatisticsProvider<Cache> noOpCacheStatisticsProvider() {
return new CacheStatisticsProvider<Cache>() { return new CacheStatisticsProvider<Cache>() {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, Cache cache) {
Cache cache) {
if (cacheManager instanceof NoOpCacheManager) { if (cacheManager instanceof NoOpCacheManager) {
return NO_OP_STATS; return NO_OP_STATS;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,19 +42,16 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
if (beans.size() == 1) { if (beans.size() == 1) {
return createHealthIndicator(beans.values().iterator().next()); return createHealthIndicator(beans.values().iterator().next());
} }
CompositeHealthIndicator composite = new CompositeHealthIndicator( CompositeHealthIndicator composite = new CompositeHealthIndicator(this.healthAggregator);
this.healthAggregator);
for (Map.Entry<String, S> entry : beans.entrySet()) { for (Map.Entry<String, S> entry : beans.entrySet()) {
composite.addHealthIndicator(entry.getKey(), composite.addHealthIndicator(entry.getKey(), createHealthIndicator(entry.getValue()));
createHealthIndicator(entry.getValue()));
} }
return composite; return composite;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected H createHealthIndicator(S source) { protected H createHealthIndicator(S source) {
Class<?>[] generics = ResolvableType Class<?>[] generics = ResolvableType.forClass(CompositeHealthIndicatorConfiguration.class, getClass())
.forClass(CompositeHealthIndicatorConfiguration.class, getClass())
.resolveGenerics(); .resolveGenerics();
Class<H> indicatorClass = (Class<H>) generics[0]; Class<H> indicatorClass = (Class<H>) generics[0];
Class<S> sourceClass = (Class<S>) generics[1]; Class<S> sourceClass = (Class<S>) generics[1];
@ -62,8 +59,8 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
return indicatorClass.getConstructor(sourceClass).newInstance(source); return indicatorClass.getConstructor(sourceClass).newInstance(source);
} }
catch (Exception ex) { catch (Exception ex) {
throw new IllegalStateException("Unable to create indicator " + indicatorClass throw new IllegalStateException(
+ " for source " + sourceClass, ex); "Unable to create indicator " + indicatorClass + " for source " + sourceClass, ex);
} }
} }

@ -120,8 +120,7 @@ import org.springframework.util.StringUtils;
@Configuration @Configuration
@ConditionalOnClass(PluginLifeCycle.class) @ConditionalOnClass(PluginLifeCycle.class)
@EnableConfigurationProperties(ShellProperties.class) @EnableConfigurationProperties(ShellProperties.class)
@AutoConfigureAfter({ SecurityAutoConfiguration.class, @AutoConfigureAfter({ SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })
ManagementWebSecurityAutoConfiguration.class })
@Deprecated @Deprecated
public class CrshAutoConfiguration { public class CrshAutoConfiguration {
@ -160,8 +159,7 @@ public class CrshAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "simple", matchIfMissing = true)
havingValue = "simple", matchIfMissing = true)
@ConditionalOnMissingBean(CrshShellAuthenticationProperties.class) @ConditionalOnMissingBean(CrshShellAuthenticationProperties.class)
public SimpleAuthenticationProperties simpleAuthenticationProperties() { public SimpleAuthenticationProperties simpleAuthenticationProperties() {
return new SimpleAuthenticationProperties(); return new SimpleAuthenticationProperties();
@ -173,16 +171,14 @@ public class CrshAutoConfiguration {
* Class to configure CRaSH to authenticate against Spring Security. * Class to configure CRaSH to authenticate against Spring Security.
*/ */
@Configuration @Configuration
@ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "spring", @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "spring", matchIfMissing = true)
matchIfMissing = true)
@ConditionalOnBean(AuthenticationManager.class) @ConditionalOnBean(AuthenticationManager.class)
@Deprecated @Deprecated
public static class AuthenticationManagerAdapterConfiguration { public static class AuthenticationManagerAdapterConfiguration {
private final ManagementServerProperties management; private final ManagementServerProperties management;
public AuthenticationManagerAdapterConfiguration( public AuthenticationManagerAdapterConfiguration(ObjectProvider<ManagementServerProperties> management) {
ObjectProvider<ManagementServerProperties> management) {
this.management = management.getIfAvailable(); this.management = management.getIfAvailable();
} }
@ -203,8 +199,7 @@ public class CrshAutoConfiguration {
SpringAuthenticationProperties authenticationProperties = new SpringAuthenticationProperties(); SpringAuthenticationProperties authenticationProperties = new SpringAuthenticationProperties();
if (this.management != null) { if (this.management != null) {
List<String> roles = this.management.getSecurity().getRoles(); List<String> roles = this.management.getSecurity().getRoles();
authenticationProperties authenticationProperties.setRoles(roles.toArray(new String[roles.size()]));
.setRoles(roles.toArray(new String[roles.size()]));
} }
return authenticationProperties; return authenticationProperties;
} }
@ -235,18 +230,14 @@ public class CrshAutoConfiguration {
@PostConstruct @PostConstruct
public void init() { public void init() {
FS commandFileSystem = createFileSystem( FS commandFileSystem = createFileSystem(this.properties.getCommandPathPatterns(),
this.properties.getCommandPathPatterns(),
this.properties.getDisabledCommands()); this.properties.getDisabledCommands());
FS configurationFileSystem = createFileSystem( FS configurationFileSystem = createFileSystem(this.properties.getConfigPathPatterns(), new String[0]);
this.properties.getConfigPathPatterns(), new String[0]);
PluginDiscovery discovery = new BeanFactoryFilteringPluginDiscovery( PluginDiscovery discovery = new BeanFactoryFilteringPluginDiscovery(this.resourceLoader.getClassLoader(),
this.resourceLoader.getClassLoader(), this.beanFactory, this.beanFactory, this.properties.getDisabledPlugins());
this.properties.getDisabledPlugins());
PluginContext context = new PluginContext(discovery, PluginContext context = new PluginContext(discovery, createPluginContextAttributes(), commandFileSystem,
createPluginContextAttributes(), commandFileSystem,
configurationFileSystem, this.resourceLoader.getClassLoader()); configurationFileSystem, this.resourceLoader.getClassLoader());
context.refresh(); context.refresh();
@ -259,12 +250,11 @@ public class CrshAutoConfiguration {
FS fileSystem = new FS(); FS fileSystem = new FS();
for (String pathPattern : pathPatterns) { for (String pathPattern : pathPatterns) {
try { try {
fileSystem.mount(new SimpleFileSystemDriver(new DirectoryHandle( fileSystem.mount(new SimpleFileSystemDriver(
pathPattern, this.resourceLoader, filterPatterns))); new DirectoryHandle(pathPattern, this.resourceLoader, filterPatterns)));
} }
catch (IOException ex) { catch (IOException ex) {
throw new IllegalStateException( throw new IllegalStateException("Failed to mount file system for '" + pathPattern + "'", ex);
"Failed to mount file system for '" + pathPattern + "'", ex);
} }
} }
return fileSystem; return fileSystem;
@ -272,8 +262,7 @@ public class CrshAutoConfiguration {
protected Map<String, Object> createPluginContextAttributes() { protected Map<String, Object> createPluginContextAttributes() {
Map<String, Object> attributes = new HashMap<String, Object>(); Map<String, Object> attributes = new HashMap<String, Object>();
String bootVersion = CrshAutoConfiguration.class.getPackage() String bootVersion = CrshAutoConfiguration.class.getPackage().getImplementationVersion();
.getImplementationVersion();
if (bootVersion != null) { if (bootVersion != null) {
attributes.put("spring.boot.version", bootVersion); attributes.put("spring.boot.version", bootVersion);
} }
@ -293,12 +282,11 @@ public class CrshAutoConfiguration {
* Adapts a Spring Security {@link AuthenticationManager} for use with CRaSH. * Adapts a Spring Security {@link AuthenticationManager} for use with CRaSH.
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private static class AuthenticationManagerAdapter extends private static class AuthenticationManagerAdapter extends CRaSHPlugin<AuthenticationPlugin>
CRaSHPlugin<AuthenticationPlugin> implements AuthenticationPlugin<String> { implements AuthenticationPlugin<String> {
private static final PropertyDescriptor<String> ROLES = PropertyDescriptor.create( private static final PropertyDescriptor<String> ROLES = PropertyDescriptor.create("auth.spring.roles",
"auth.spring.roles", "ACTUATOR", "ACTUATOR", "Comma separated list of roles required to access the shell");
"Comma separated list of roles required to access the shell");
@Autowired @Autowired
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
@ -311,8 +299,7 @@ public class CrshAutoConfiguration {
@Override @Override
public boolean authenticate(String username, String password) throws Exception { public boolean authenticate(String username, String password) throws Exception {
Authentication token = new UsernamePasswordAuthenticationToken(username, Authentication token = new UsernamePasswordAuthenticationToken(username, password);
password);
try { try {
// Authenticate first to make sure credentials are valid // Authenticate first to make sure credentials are valid
token = this.authenticationManager.authenticate(token); token = this.authenticationManager.authenticate(token);
@ -322,11 +309,9 @@ public class CrshAutoConfiguration {
} }
// Test access rights if a Spring Security AccessDecisionManager is installed // Test access rights if a Spring Security AccessDecisionManager is installed
if (this.accessDecisionManager != null && token.isAuthenticated() if (this.accessDecisionManager != null && token.isAuthenticated() && this.roles != null) {
&& this.roles != null) {
try { try {
this.accessDecisionManager.decide(token, this, this.accessDecisionManager.decide(token, this, SecurityConfig.createList(this.roles));
SecurityConfig.createList(this.roles));
} }
catch (AccessDeniedException ex) { catch (AccessDeniedException ex) {
return false; return false;
@ -354,8 +339,7 @@ public class CrshAutoConfiguration {
public void init() { public void init() {
String rolesPropertyValue = getContext().getProperty(ROLES); String rolesPropertyValue = getContext().getProperty(ROLES);
if (rolesPropertyValue != null) { if (rolesPropertyValue != null) {
this.roles = StringUtils this.roles = StringUtils.commaDelimitedListToStringArray(rolesPropertyValue);
.commaDelimitedListToStringArray(rolesPropertyValue);
} }
} }
@ -370,16 +354,14 @@ public class CrshAutoConfiguration {
* {@link ServiceLoaderDiscovery} to expose {@link CRaSHPlugin} Beans from Spring and * {@link ServiceLoaderDiscovery} to expose {@link CRaSHPlugin} Beans from Spring and
* deal with filtering disabled plugins. * deal with filtering disabled plugins.
*/ */
private static class BeanFactoryFilteringPluginDiscovery private static class BeanFactoryFilteringPluginDiscovery extends ServiceLoaderDiscovery {
extends ServiceLoaderDiscovery {
private final ListableBeanFactory beanFactory; private final ListableBeanFactory beanFactory;
private final String[] disabledPlugins; private final String[] disabledPlugins;
BeanFactoryFilteringPluginDiscovery(ClassLoader classLoader, BeanFactoryFilteringPluginDiscovery(ClassLoader classLoader, ListableBeanFactory beanFactory,
ListableBeanFactory beanFactory, String[] disabledPlugins) String[] disabledPlugins) throws NullPointerException {
throws NullPointerException {
super(classLoader); super(classLoader);
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
this.disabledPlugins = disabledPlugins; this.disabledPlugins = disabledPlugins;
@ -396,8 +378,7 @@ public class CrshAutoConfiguration {
} }
} }
Collection<CRaSHPlugin> pluginBeans = this.beanFactory Collection<CRaSHPlugin> pluginBeans = this.beanFactory.getBeansOfType(CRaSHPlugin.class).values();
.getBeansOfType(CRaSHPlugin.class).values();
for (CRaSHPlugin<?> pluginBean : pluginBeans) { for (CRaSHPlugin<?> pluginBean : pluginBeans) {
if (isEnabled(pluginBean)) { if (isEnabled(pluginBean)) {
plugins.add(pluginBean); plugins.add(pluginBean);
@ -428,8 +409,7 @@ public class CrshAutoConfiguration {
private boolean isEnabled(Class<?> pluginClass) { private boolean isEnabled(Class<?> pluginClass) {
for (String disabledPlugin : this.disabledPlugins) { for (String disabledPlugin : this.disabledPlugins) {
if (ClassUtils.getShortName(pluginClass).equalsIgnoreCase(disabledPlugin) if (ClassUtils.getShortName(pluginClass).equalsIgnoreCase(disabledPlugin)
|| ClassUtils.getQualifiedName(pluginClass) || ClassUtils.getQualifiedName(pluginClass).equalsIgnoreCase(disabledPlugin)) {
.equalsIgnoreCase(disabledPlugin)) {
return false; return false;
} }
} }
@ -450,8 +430,7 @@ public class CrshAutoConfiguration {
} }
@Override @Override
public Iterable<ResourceHandle> children(ResourceHandle handle) public Iterable<ResourceHandle> children(ResourceHandle handle) throws IOException {
throws IOException {
if (handle instanceof DirectoryHandle) { if (handle instanceof DirectoryHandle) {
return ((DirectoryHandle) handle).members(); return ((DirectoryHandle) handle).members();
} }
@ -479,8 +458,7 @@ public class CrshAutoConfiguration {
@Override @Override
public Iterator<InputStream> open(ResourceHandle handle) throws IOException { public Iterator<InputStream> open(ResourceHandle handle) throws IOException {
if (handle instanceof FileHandle) { if (handle instanceof FileHandle) {
return Collections.singletonList(((FileHandle) handle).openStream()) return Collections.singletonList(((FileHandle) handle).openStream()).iterator();
.iterator();
} }
return Collections.<InputStream>emptyList().iterator(); return Collections.<InputStream>emptyList().iterator();
} }
@ -520,8 +498,7 @@ public class CrshAutoConfiguration {
private final AntPathMatcher matcher = new AntPathMatcher(); private final AntPathMatcher matcher = new AntPathMatcher();
DirectoryHandle(String name, ResourcePatternResolver resourceLoader, DirectoryHandle(String name, ResourcePatternResolver resourceLoader, String[] filterPatterns) {
String[] filterPatterns) {
super(name); super(name);
this.resourceLoader = resourceLoader; this.resourceLoader = resourceLoader;
this.filterPatterns = filterPatterns; this.filterPatterns = filterPatterns;
@ -531,8 +508,7 @@ public class CrshAutoConfiguration {
Resource[] resources = this.resourceLoader.getResources(getName()); Resource[] resources = this.resourceLoader.getResources(getName());
List<ResourceHandle> files = new ArrayList<ResourceHandle>(); List<ResourceHandle> files = new ArrayList<ResourceHandle>();
for (Resource resource : resources) { for (Resource resource : resources) {
if (!resource.getURL().getPath().endsWith("/") if (!resource.getURL().getPath().endsWith("/") && !shouldFilter(resource)) {
&& !shouldFilter(resource)) {
files.add(new FileHandle(resource.getFilename(), resource)); files.add(new FileHandle(resource.getFilename(), resource));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,8 +43,8 @@ class ElasticsearchHealthIndicatorConfiguration {
@ConditionalOnBean(Client.class) @ConditionalOnBean(Client.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch") @ConditionalOnEnabledHealthIndicator("elasticsearch")
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class) @EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
static class ElasticsearchClientHealthIndicatorConfiguration extends static class ElasticsearchClientHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> { extends CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
private final Map<String, Client> clients; private final Map<String, Client> clients;
@ -72,8 +72,8 @@ class ElasticsearchHealthIndicatorConfiguration {
@Configuration @Configuration
@ConditionalOnBean(JestClient.class) @ConditionalOnBean(JestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch") @ConditionalOnEnabledHealthIndicator("elasticsearch")
static class ElasticsearchJestHealthIndicatorConfiguration extends static class ElasticsearchJestHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> { extends CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
private final Map<String, JestClient> clients; private final Map<String, JestClient> clients;
@ -88,8 +88,7 @@ class ElasticsearchHealthIndicatorConfiguration {
} }
@Override @Override
protected ElasticsearchJestHealthIndicator createHealthIndicator( protected ElasticsearchJestHealthIndicator createHealthIndicator(JestClient client) {
JestClient client) {
return new ElasticsearchJestHealthIndicator(client); return new ElasticsearchJestHealthIndicator(client);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -96,8 +96,7 @@ public class EndpointAutoConfiguration {
public EndpointAutoConfiguration(ObjectProvider<HealthAggregator> healthAggregator, public EndpointAutoConfiguration(ObjectProvider<HealthAggregator> healthAggregator,
ObjectProvider<Map<String, HealthIndicator>> healthIndicators, ObjectProvider<Map<String, HealthIndicator>> healthIndicators,
ObjectProvider<List<InfoContributor>> infoContributors, ObjectProvider<List<InfoContributor>> infoContributors,
ObjectProvider<Collection<PublicMetrics>> publicMetrics, ObjectProvider<Collection<PublicMetrics>> publicMetrics, ObjectProvider<TraceRepository> traceRepository) {
ObjectProvider<TraceRepository> traceRepository) {
this.healthAggregator = healthAggregator.getIfAvailable(); this.healthAggregator = healthAggregator.getIfAvailable();
this.healthIndicators = healthIndicators.getIfAvailable(); this.healthIndicators = healthIndicators.getIfAvailable();
this.infoContributors = infoContributors.getIfAvailable(); this.infoContributors = infoContributors.getIfAvailable();
@ -114,10 +113,10 @@ public class EndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HealthEndpoint healthEndpoint() { public HealthEndpoint healthEndpoint() {
HealthAggregator healthAggregator = (this.healthAggregator != null) HealthAggregator healthAggregator = (this.healthAggregator != null) ? this.healthAggregator
? this.healthAggregator : new OrderedHealthAggregator(); : new OrderedHealthAggregator();
Map<String, HealthIndicator> healthIndicators = (this.healthIndicators != null) Map<String, HealthIndicator> healthIndicators = (this.healthIndicators != null) ? this.healthIndicators
? this.healthIndicators : Collections.<String, HealthIndicator>emptyMap(); : Collections.<String, HealthIndicator>emptyMap();
return new HealthEndpoint(healthAggregator, healthIndicators); return new HealthEndpoint(healthAggregator, healthIndicators);
} }
@ -130,8 +129,8 @@ public class EndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public InfoEndpoint infoEndpoint() throws Exception { public InfoEndpoint infoEndpoint() throws Exception {
return new InfoEndpoint((this.infoContributors != null) ? this.infoContributors return new InfoEndpoint(
: Collections.<InfoContributor>emptyList()); (this.infoContributors != null) ? this.infoContributors : Collections.<InfoContributor>emptyList());
} }
@Bean @Bean
@ -155,8 +154,7 @@ public class EndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public TraceEndpoint traceEndpoint() { public TraceEndpoint traceEndpoint() {
return new TraceEndpoint((this.traceRepository != null) ? this.traceRepository return new TraceEndpoint((this.traceRepository != null) ? this.traceRepository : new InMemoryTraceRepository());
: new InMemoryTraceRepository());
} }
@Bean @Bean
@ -204,8 +202,7 @@ public class EndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public LiquibaseEndpoint liquibaseEndpoint( public LiquibaseEndpoint liquibaseEndpoint(Map<String, SpringLiquibase> liquibases) {
Map<String, SpringLiquibase> liquibases) {
return new LiquibaseEndpoint(liquibases); return new LiquibaseEndpoint(liquibases);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,8 +69,7 @@ public class EndpointMBeanExportAutoConfiguration {
@Bean @Bean
public EndpointMBeanExporter endpointMBeanExporter(MBeanServer server) { public EndpointMBeanExporter endpointMBeanExporter(MBeanServer server) {
EndpointMBeanExporter mbeanExporter = new EndpointMBeanExporter( EndpointMBeanExporter mbeanExporter = new EndpointMBeanExporter(this.objectMapper);
this.objectMapper);
String domain = this.properties.getDomain(); String domain = this.properties.getDomain();
if (StringUtils.hasText(domain)) { if (StringUtils.hasText(domain)) {
mbeanExporter.setDomain(domain); mbeanExporter.setDomain(domain);
@ -90,8 +89,7 @@ public class EndpointMBeanExportAutoConfiguration {
@Bean @Bean
@ConditionalOnBean(AuditEventRepository.class) @ConditionalOnBean(AuditEventRepository.class)
@ConditionalOnEnabledEndpoint("auditevents") @ConditionalOnEnabledEndpoint("auditevents")
public AuditEventsJmxEndpoint auditEventsEndpoint( public AuditEventsJmxEndpoint auditEventsEndpoint(AuditEventRepository auditEventRepository) {
AuditEventRepository auditEventRepository) {
return new AuditEventsJmxEndpoint(this.objectMapper, auditEventRepository); return new AuditEventsJmxEndpoint(this.objectMapper, auditEventRepository);
} }
@ -101,13 +99,11 @@ public class EndpointMBeanExportAutoConfiguration {
static class JmxEnabledCondition extends SpringBootCondition { static class JmxEnabledCondition extends SpringBootCondition {
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) {
boolean jmxEnabled = isEnabled(context, "spring.jmx."); boolean jmxEnabled = isEnabled(context, "spring.jmx.");
boolean jmxEndpointsEnabled = isEnabled(context, "endpoints.jmx."); boolean jmxEndpointsEnabled = isEnabled(context, "endpoints.jmx.");
if (jmxEnabled && jmxEndpointsEnabled) { if (jmxEnabled && jmxEndpointsEnabled) {
return ConditionOutcome.match( return ConditionOutcome.match(ConditionMessage.forCondition("JMX Enabled").found("properties")
ConditionMessage.forCondition("JMX Enabled").found("properties")
.items("spring.jmx.enabled", "endpoints.jmx.enabled")); .items("spring.jmx.enabled", "endpoints.jmx.enabled"));
} }
return ConditionOutcome.noMatch(ConditionMessage.forCondition("JMX Enabled") return ConditionOutcome.noMatch(ConditionMessage.forCondition("JMX Enabled")
@ -115,8 +111,7 @@ public class EndpointMBeanExportAutoConfiguration {
} }
private boolean isEnabled(ConditionContext context, String prefix) { private boolean isEnabled(ConditionContext context, String prefix) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
context.getEnvironment(), prefix);
return resolver.getProperty("enabled", Boolean.class, true); return resolver.getProperty("enabled", Boolean.class, true);
} }

@ -98,24 +98,21 @@ import org.springframework.web.servlet.DispatcherServlet;
@Configuration @Configuration
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
@ConditionalOnWebApplication @ConditionalOnWebApplication
@AutoConfigureAfter({ PropertyPlaceholderAutoConfiguration.class, @AutoConfigureAfter({ PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class,
EmbeddedServletContainerAutoConfiguration.class, WebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
RepositoryRestMvcAutoConfiguration.class, HypermediaAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, HypermediaAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class }) HttpMessageConvertersAutoConfiguration.class })
public class EndpointWebMvcAutoConfiguration public class EndpointWebMvcAutoConfiguration
implements ApplicationContextAware, BeanFactoryAware, SmartInitializingSingleton { implements ApplicationContextAware, BeanFactoryAware, SmartInitializingSingleton {
private static final Log logger = LogFactory private static final Log logger = LogFactory.getLog(EndpointWebMvcAutoConfiguration.class);
.getLog(EndpointWebMvcAutoConfiguration.class);
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private BeanFactory beanFactory; private BeanFactory beanFactory;
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
throws BeansException {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }
@ -130,8 +127,7 @@ public class EndpointWebMvcAutoConfiguration
} }
@Bean @Bean
public ManagementServletContext managementServletContext( public ManagementServletContext managementServletContext(final ManagementServerProperties properties) {
final ManagementServerProperties properties) {
return new ManagementServletContext() { return new ManagementServletContext() {
@Override @Override
@ -146,8 +142,7 @@ public class EndpointWebMvcAutoConfiguration
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
ManagementServerPort managementPort = ManagementServerPort.DIFFERENT; ManagementServerPort managementPort = ManagementServerPort.DIFFERENT;
if (this.applicationContext instanceof WebApplicationContext) { if (this.applicationContext instanceof WebApplicationContext) {
managementPort = ManagementServerPort managementPort = ManagementServerPort.get(this.applicationContext.getEnvironment(), this.beanFactory);
.get(this.applicationContext.getEnvironment(), this.beanFactory);
} }
if (managementPort == ManagementServerPort.DIFFERENT) { if (managementPort == ManagementServerPort.DIFFERENT) {
if (this.applicationContext instanceof EmbeddedWebApplicationContext if (this.applicationContext instanceof EmbeddedWebApplicationContext
@ -157,22 +152,17 @@ public class EndpointWebMvcAutoConfiguration
} }
else { else {
logger.warn("Could not start embedded management container on " logger.warn("Could not start embedded management container on "
+ "different port (management endpoints are still available " + "different port (management endpoints are still available " + "through JMX)");
+ "through JMX)");
} }
} }
if (managementPort == ManagementServerPort.SAME) { if (managementPort == ManagementServerPort.SAME) {
if (new RelaxedPropertyResolver(this.applicationContext.getEnvironment(), if (new RelaxedPropertyResolver(this.applicationContext.getEnvironment(), "management.ssl.")
"management.ssl.").getProperty("enabled", Boolean.class, false)) { .getProperty("enabled", Boolean.class, false)) {
throw new IllegalStateException( throw new IllegalStateException("Management-specific SSL cannot be configured as the management "
"Management-specific SSL cannot be configured as the management "
+ "server is not listening on a separate port"); + "server is not listening on a separate port");
} }
if (this.applicationContext if (this.applicationContext.getEnvironment() instanceof ConfigurableEnvironment) {
.getEnvironment() instanceof ConfigurableEnvironment) { addLocalManagementPortPropertyAlias((ConfigurableEnvironment) this.applicationContext.getEnvironment());
addLocalManagementPortPropertyAlias(
(ConfigurableEnvironment) this.applicationContext
.getEnvironment());
} }
} }
} }
@ -183,26 +173,21 @@ public class EndpointWebMvcAutoConfiguration
childContext.setNamespace("management"); childContext.setNamespace("management");
childContext.setId(this.applicationContext.getId() + ":management"); childContext.setId(this.applicationContext.getId() + ":management");
childContext.setClassLoader(this.applicationContext.getClassLoader()); childContext.setClassLoader(this.applicationContext.getClassLoader());
childContext.register(EndpointWebMvcChildContextConfiguration.class, childContext.register(EndpointWebMvcChildContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, DispatcherServletAutoConfiguration.class);
EmbeddedServletContainerAutoConfiguration.class,
DispatcherServletAutoConfiguration.class);
registerEmbeddedServletContainerFactory(childContext); registerEmbeddedServletContainerFactory(childContext);
CloseManagementContextListener.addIfPossible(this.applicationContext, CloseManagementContextListener.addIfPossible(this.applicationContext, childContext);
childContext);
childContext.refresh(); childContext.refresh();
managementContextResolver().setApplicationContext(childContext); managementContextResolver().setApplicationContext(childContext);
} }
private void registerEmbeddedServletContainerFactory( private void registerEmbeddedServletContainerFactory(AnnotationConfigEmbeddedWebApplicationContext childContext) {
AnnotationConfigEmbeddedWebApplicationContext childContext) {
try { try {
ConfigurableListableBeanFactory beanFactory = childContext.getBeanFactory(); ConfigurableListableBeanFactory beanFactory = childContext.getBeanFactory();
if (beanFactory instanceof BeanDefinitionRegistry) { if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
registry.registerBeanDefinition("embeddedServletContainerFactory", registry.registerBeanDefinition("embeddedServletContainerFactory",
new RootBeanDefinition( new RootBeanDefinition(determineEmbeddedServletContainerFactoryClass()));
determineEmbeddedServletContainerFactoryClass()));
} }
} }
catch (NoSuchBeanDefinitionException ex) { catch (NoSuchBeanDefinitionException ex) {
@ -210,10 +195,9 @@ public class EndpointWebMvcAutoConfiguration
} }
} }
private Class<?> determineEmbeddedServletContainerFactoryClass() private Class<?> determineEmbeddedServletContainerFactoryClass() throws NoSuchBeanDefinitionException {
throws NoSuchBeanDefinitionException { Class<?> servletContainerFactoryClass = this.applicationContext.getBean(EmbeddedServletContainerFactory.class)
Class<?> servletContainerFactoryClass = this.applicationContext .getClass();
.getBean(EmbeddedServletContainerFactory.class).getClass();
if (cannotBeInstantiated(servletContainerFactoryClass)) { if (cannotBeInstantiated(servletContainerFactoryClass)) {
throw new FatalBeanException("EmbeddedServletContainerFactory implementation " throw new FatalBeanException("EmbeddedServletContainerFactory implementation "
+ servletContainerFactoryClass.getName() + " cannot be instantiated. " + servletContainerFactoryClass.getName() + " cannot be instantiated. "
@ -224,8 +208,7 @@ public class EndpointWebMvcAutoConfiguration
} }
private boolean cannotBeInstantiated(Class<?> clazz) { private boolean cannotBeInstantiated(Class<?> clazz) {
return clazz.isLocalClass() return clazz.isLocalClass() || (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers()))
|| (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers()))
|| clazz.isAnonymousClass(); || clazz.isAnonymousClass();
} }
@ -234,10 +217,8 @@ public class EndpointWebMvcAutoConfiguration
* 'local.server.port'. * 'local.server.port'.
* @param environment the environment * @param environment the environment
*/ */
private void addLocalManagementPortPropertyAlias( private void addLocalManagementPortPropertyAlias(final ConfigurableEnvironment environment) {
final ConfigurableEnvironment environment) { environment.getPropertySources().addLast(new PropertySource<Object>("Management Server") {
environment.getPropertySources()
.addLast(new PropertySource<Object>("Management Server") {
@Override @Override
public Object getProperty(String name) { public Object getProperty(String name) {
if ("local.management.port".equals(name)) { if ("local.management.port".equals(name)) {
@ -251,13 +232,12 @@ public class EndpointWebMvcAutoConfiguration
// Put Servlets and Filters in their own nested class so they don't force early // Put Servlets and Filters in their own nested class so they don't force early
// instantiation of ManagementServerProperties. // instantiation of ManagementServerProperties.
@Configuration @Configuration
@ConditionalOnProperty(prefix = "management", name = "add-application-context-header", @ConditionalOnProperty(prefix = "management", name = "add-application-context-header", matchIfMissing = true,
matchIfMissing = true, havingValue = "true") havingValue = "true")
protected static class ApplicationContextFilterConfiguration { protected static class ApplicationContextFilterConfiguration {
@Bean @Bean
public ApplicationContextHeaderFilter applicationContextIdFilter( public ApplicationContextHeaderFilter applicationContextIdFilter(ApplicationContext context) {
ApplicationContext context) {
return new ApplicationContextHeaderFilter(context); return new ApplicationContextHeaderFilter(context);
} }
@ -274,15 +254,13 @@ public class EndpointWebMvcAutoConfiguration
* {@link ApplicationListener} to propagate the {@link ContextClosedEvent} and * {@link ApplicationListener} to propagate the {@link ContextClosedEvent} and
* {@link ApplicationFailedEvent} from a parent to a child. * {@link ApplicationFailedEvent} from a parent to a child.
*/ */
private static class CloseManagementContextListener private static class CloseManagementContextListener implements ApplicationListener<ApplicationEvent> {
implements ApplicationListener<ApplicationEvent> {
private final ApplicationContext parentContext; private final ApplicationContext parentContext;
private final ConfigurableApplicationContext childContext; private final ConfigurableApplicationContext childContext;
CloseManagementContextListener(ApplicationContext parentContext, CloseManagementContextListener(ApplicationContext parentContext, ConfigurableApplicationContext childContext) {
ConfigurableApplicationContext childContext) {
this.parentContext = parentContext; this.parentContext = parentContext;
this.childContext = childContext; this.childContext = childContext;
} }
@ -320,14 +298,12 @@ public class EndpointWebMvcAutoConfiguration
private static void add(ConfigurableApplicationContext parentContext, private static void add(ConfigurableApplicationContext parentContext,
ConfigurableApplicationContext childContext) { ConfigurableApplicationContext childContext) {
parentContext.addApplicationListener( parentContext.addApplicationListener(new CloseManagementContextListener(parentContext, childContext));
new CloseManagementContextListener(parentContext, childContext));
} }
} }
private static class OnManagementMvcCondition extends SpringBootCondition private static class OnManagementMvcCondition extends SpringBootCondition implements ConfigurationCondition {
implements ConfigurationCondition {
@Override @Override
public ConfigurationPhase getConfigurationPhase() { public ConfigurationPhase getConfigurationPhase() {
@ -335,16 +311,12 @@ public class EndpointWebMvcAutoConfiguration
} }
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) { ConditionMessage.Builder message = ConditionMessage.forCondition("Management Server MVC");
ConditionMessage.Builder message = ConditionMessage
.forCondition("Management Server MVC");
if (!(context.getResourceLoader() instanceof WebApplicationContext)) { if (!(context.getResourceLoader() instanceof WebApplicationContext)) {
return ConditionOutcome return ConditionOutcome.noMatch(message.because("non WebApplicationContext"));
.noMatch(message.because("non WebApplicationContext"));
} }
ManagementServerPort port = ManagementServerPort.get(context.getEnvironment(), ManagementServerPort port = ManagementServerPort.get(context.getEnvironment(), context.getBeanFactory());
context.getBeanFactory());
if (port == ManagementServerPort.SAME) { if (port == ManagementServerPort.SAME) {
return ConditionOutcome.match(message.because("port is same")); return ConditionOutcome.match(message.because("port is same"));
} }
@ -357,28 +329,22 @@ public class EndpointWebMvcAutoConfiguration
DISABLE, SAME, DIFFERENT; DISABLE, SAME, DIFFERENT;
public static ManagementServerPort get(Environment environment, public static ManagementServerPort get(Environment environment, BeanFactory beanFactory) {
BeanFactory beanFactory) {
Integer serverPort = getPortProperty(environment, "server."); Integer serverPort = getPortProperty(environment, "server.");
if (serverPort == null && hasCustomBeanDefinition(beanFactory, if (serverPort == null && hasCustomBeanDefinition(beanFactory, ServerProperties.class,
ServerProperties.class, ServerPropertiesAutoConfiguration.class)) { ServerPropertiesAutoConfiguration.class)) {
serverPort = getTemporaryBean(beanFactory, ServerProperties.class) serverPort = getTemporaryBean(beanFactory, ServerProperties.class).getPort();
.getPort();
} }
Integer managementPort = getPortProperty(environment, "management."); Integer managementPort = getPortProperty(environment, "management.");
if (managementPort == null && hasCustomBeanDefinition(beanFactory, if (managementPort == null && hasCustomBeanDefinition(beanFactory, ManagementServerProperties.class,
ManagementServerProperties.class,
ManagementServerPropertiesAutoConfiguration.class)) { ManagementServerPropertiesAutoConfiguration.class)) {
managementPort = getTemporaryBean(beanFactory, managementPort = getTemporaryBean(beanFactory, ManagementServerProperties.class).getPort();
ManagementServerProperties.class).getPort();
} }
if (managementPort != null && managementPort < 0) { if (managementPort != null && managementPort < 0) {
return DISABLE; return DISABLE;
} }
return ((managementPort == null) return ((managementPort == null) || (serverPort == null && managementPort.equals(8080))
|| (serverPort == null && managementPort.equals(8080)) || (managementPort != 0) && managementPort.equals(serverPort)) ? SAME : DIFFERENT;
|| (managementPort != 0) && managementPort.equals(serverPort)) ? SAME
: DIFFERENT;
} }
private static <T> T getTemporaryBean(BeanFactory beanFactory, Class<T> type) { private static <T> T getTemporaryBean(BeanFactory beanFactory, Class<T> type) {
@ -392,35 +358,30 @@ public class EndpointWebMvcAutoConfiguration
} }
// Use a temporary child bean factory to avoid instantiating the bean in the // Use a temporary child bean factory to avoid instantiating the bean in the
// parent (it won't be bound to the environment yet) // parent (it won't be bound to the environment yet)
return createTemporaryBean(type, listable, return createTemporaryBean(type, listable, listable.getBeanDefinition(names[0]));
listable.getBeanDefinition(names[0]));
} }
private static <T> T createTemporaryBean(Class<T> type, private static <T> T createTemporaryBean(Class<T> type, ConfigurableListableBeanFactory parent,
ConfigurableListableBeanFactory parent, BeanDefinition definition) { BeanDefinition definition) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory( DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(parent);
parent);
beanFactory.registerBeanDefinition(type.getName(), definition); beanFactory.registerBeanDefinition(type.getName(), definition);
return beanFactory.getBean(type); return beanFactory.getBean(type);
} }
private static Integer getPortProperty(Environment environment, String prefix) { private static Integer getPortProperty(Environment environment, String prefix) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, prefix);
prefix);
return resolver.getProperty("port", Integer.class); return resolver.getProperty("port", Integer.class);
} }
private static <T> boolean hasCustomBeanDefinition(BeanFactory beanFactory, private static <T> boolean hasCustomBeanDefinition(BeanFactory beanFactory, Class<T> type,
Class<T> type, Class<?> configClass) { Class<?> configClass) {
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
return false; return false;
} }
return hasCustomBeanDefinition((ConfigurableListableBeanFactory) beanFactory, return hasCustomBeanDefinition((ConfigurableListableBeanFactory) beanFactory, type, configClass);
type, configClass);
} }
private static <T> boolean hasCustomBeanDefinition( private static <T> boolean hasCustomBeanDefinition(ConfigurableListableBeanFactory beanFactory, Class<T> type,
ConfigurableListableBeanFactory beanFactory, Class<T> type,
Class<?> configClass) { Class<?> configClass) {
String[] names = beanFactory.getBeanNamesForType(type, true, false); String[] names = beanFactory.getBeanNamesForType(type, true, false);
if (names == null || names.length != 1) { if (names == null || names.length != 1) {

@ -142,8 +142,8 @@ public class EndpointWebMvcChildContextConfiguration {
protected static class EndpointHandlerMappingConfiguration { protected static class EndpointHandlerMappingConfiguration {
@Autowired @Autowired
public void handlerMapping(MvcEndpoints endpoints, public void handlerMapping(MvcEndpoints endpoints, ListableBeanFactory beanFactory,
ListableBeanFactory beanFactory, EndpointHandlerMapping mapping) { EndpointHandlerMapping mapping) {
// In a child context we definitely want to see the parent endpoints // In a child context we definitely want to see the parent endpoints
mapping.setDetectHandlerMethodsInAncestorContexts(true); mapping.setDetectHandlerMethodsInAncestorContexts(true);
} }
@ -152,8 +152,7 @@ public class EndpointWebMvcChildContextConfiguration {
@Configuration @Configuration
@ConditionalOnClass({ EnableWebSecurity.class, Filter.class }) @ConditionalOnClass({ EnableWebSecurity.class, Filter.class })
@ConditionalOnBean(name = "springSecurityFilterChain", @ConditionalOnBean(name = "springSecurityFilterChain", search = SearchStrategy.ANCESTORS)
search = SearchStrategy.ANCESTORS)
public static class EndpointWebMvcChildContextSecurityConfiguration { public static class EndpointWebMvcChildContextSecurityConfiguration {
@Bean @Bean
@ -172,8 +171,7 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static class ServerCustomization static class ServerCustomization implements EmbeddedServletContainerCustomizer, Ordered {
implements EmbeddedServletContainerCustomizer, Ordered {
@Autowired @Autowired
private ListableBeanFactory beanFactory; private ListableBeanFactory beanFactory;
@ -192,11 +190,9 @@ public class EndpointWebMvcChildContextConfiguration {
@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.server = BeanFactoryUtils.beanOfTypeIncludingAncestors(this.beanFactory, ServerProperties.class);
this.beanFactory, ServerProperties.class);
} }
// Customize as per the parent context first (so e.g. the access logs go to // Customize as per the parent context first (so e.g. the access logs go to
// the same place) // the same place)
@ -225,8 +221,7 @@ public class EndpointWebMvcChildContextConfiguration {
private List<HandlerMapping> mappings; private List<HandlerMapping> mappings;
@Override @Override
public HandlerExecutionChain getHandler(HttpServletRequest request) public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
throws Exception {
if (this.mappings == null) { if (this.mappings == null) {
this.mappings = extractMappings(); this.mappings = extractMappings();
} }
@ -278,8 +273,8 @@ public class EndpointWebMvcChildContextConfiguration {
} }
@Override @Override
public ModelAndView handle(HttpServletRequest request, public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
HttpServletResponse response, Object handler) throws Exception { throws Exception {
if (this.adapters == null) { if (this.adapters == null) {
this.adapters = extractAdapters(); this.adapters = extractAdapters();
} }
@ -315,8 +310,7 @@ public class EndpointWebMvcChildContextConfiguration {
private List<HandlerExceptionResolver> extractResolvers() { private List<HandlerExceptionResolver> extractResolvers() {
List<HandlerExceptionResolver> list = new ArrayList<HandlerExceptionResolver>(); List<HandlerExceptionResolver> list = new ArrayList<HandlerExceptionResolver>();
list.addAll(this.beanFactory.getBeansOfType(HandlerExceptionResolver.class) list.addAll(this.beanFactory.getBeansOfType(HandlerExceptionResolver.class).values());
.values());
list.remove(this); list.remove(this);
AnnotationAwareOrderComparator.sort(list); AnnotationAwareOrderComparator.sort(list);
if (list.isEmpty()) { if (list.isEmpty()) {
@ -326,14 +320,13 @@ public class EndpointWebMvcChildContextConfiguration {
} }
@Override @Override
public ModelAndView resolveException(HttpServletRequest request, public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
HttpServletResponse response, Object handler, Exception ex) { Exception ex) {
if (this.resolvers == null) { if (this.resolvers == null) {
this.resolvers = extractResolvers(); this.resolvers = extractResolvers();
} }
for (HandlerExceptionResolver mapping : this.resolvers) { for (HandlerExceptionResolver mapping : this.resolvers) {
ModelAndView mav = mapping.resolveException(request, response, handler, ModelAndView mav = mapping.resolveException(request, response, handler, ex);
ex);
if (mav != null) { if (mav != null) {
return mav; return mav;
} }
@ -372,8 +365,7 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static class TomcatAccessLogCustomizer static class TomcatAccessLogCustomizer extends AccessLogCustomizer<TomcatEmbeddedServletContainerFactory> {
extends AccessLogCustomizer<TomcatEmbeddedServletContainerFactory> {
TomcatAccessLogCustomizer() { TomcatAccessLogCustomizer() {
super(TomcatEmbeddedServletContainerFactory.class); super(TomcatEmbeddedServletContainerFactory.class);
@ -388,8 +380,7 @@ public class EndpointWebMvcChildContextConfiguration {
accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix())); accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix()));
} }
private AccessLogValve findAccessLogValve( private AccessLogValve findAccessLogValve(TomcatEmbeddedServletContainerFactory container) {
TomcatEmbeddedServletContainerFactory container) {
for (Valve engineValve : container.getEngineValves()) { for (Valve engineValve : container.getEngineValves()) {
if (engineValve instanceof AccessLogValve) { if (engineValve instanceof AccessLogValve) {
return (AccessLogValve) engineValve; return (AccessLogValve) engineValve;
@ -400,8 +391,7 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static class UndertowAccessLogCustomizer static class UndertowAccessLogCustomizer extends AccessLogCustomizer<UndertowEmbeddedServletContainerFactory> {
extends AccessLogCustomizer<UndertowEmbeddedServletContainerFactory> {
UndertowAccessLogCustomizer() { UndertowAccessLogCustomizer() {
super(UndertowEmbeddedServletContainerFactory.class); super(UndertowEmbeddedServletContainerFactory.class);

@ -99,8 +99,7 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
public class EndpointWebMvcHypermediaManagementContextConfiguration { public class EndpointWebMvcHypermediaManagementContextConfiguration {
@Bean @Bean
public ManagementServletContext managementServletContext( public ManagementServletContext managementServletContext(final ManagementServerProperties properties) {
final ManagementServerProperties properties) {
return new ManagementServletContext() { return new ManagementServletContext() {
@Override @Override
@ -114,8 +113,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@Bean @Bean
@ConditionalOnEnabledEndpoint("actuator") @ConditionalOnEnabledEndpoint("actuator")
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HalJsonMvcEndpoint halJsonMvcEndpoint( public HalJsonMvcEndpoint halJsonMvcEndpoint(ManagementServletContext managementServletContext,
ManagementServletContext managementServletContext,
ResourceProperties resources, ResourceLoader resourceLoader) { ResourceProperties resources, ResourceLoader resourceLoader) {
if (HalBrowserMvcEndpoint.getHalBrowserLocation(resourceLoader) != null) { if (HalBrowserMvcEndpoint.getHalBrowserLocation(resourceLoader) != null) {
return new HalBrowserMvcEndpoint(managementServletContext); return new HalBrowserMvcEndpoint(managementServletContext);
@ -126,12 +124,10 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@Bean @Bean
@ConditionalOnBean(DocsMvcEndpoint.class) @ConditionalOnBean(DocsMvcEndpoint.class)
@ConditionalOnMissingBean(CurieProvider.class) @ConditionalOnMissingBean(CurieProvider.class)
@ConditionalOnProperty(prefix = "endpoints.docs.curies", name = "enabled", @ConditionalOnProperty(prefix = "endpoints.docs.curies", name = "enabled", matchIfMissing = false)
matchIfMissing = false) public DefaultCurieProvider curieProvider(ServerProperties server, ManagementServerProperties management,
public DefaultCurieProvider curieProvider(ServerProperties server, DocsMvcEndpoint endpoint) {
ManagementServerProperties management, DocsMvcEndpoint endpoint) { String path = management.getContextPath() + endpoint.getPath() + "/#spring_boot_actuator__{rel}";
String path = management.getContextPath() + endpoint.getPath()
+ "/#spring_boot_actuator__{rel}";
return new DefaultCurieProvider("boot", new UriTemplate(path)); return new DefaultCurieProvider("boot", new UriTemplate(path));
} }
@ -141,10 +137,8 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint("docs") @ConditionalOnEnabledEndpoint("docs")
@ConditionalOnResource( @ConditionalOnResource(resources = "classpath:/META-INF/resources/spring-boot-actuator/docs/index.html")
resources = "classpath:/META-INF/resources/spring-boot-actuator/docs/index.html") public DocsMvcEndpoint docsMvcEndpoint(ManagementServletContext managementServletContext) {
public DocsMvcEndpoint docsMvcEndpoint(
ManagementServletContext managementServletContext) {
return new DocsMvcEndpoint(managementServletContext); return new DocsMvcEndpoint(managementServletContext);
} }
@ -154,8 +148,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
* Controller advice that adds links to the actuator endpoint's path. * Controller advice that adds links to the actuator endpoint's path.
*/ */
@ControllerAdvice @ControllerAdvice
public static class ActuatorEndpointLinksAdvice public static class ActuatorEndpointLinksAdvice implements ResponseBodyAdvice<Object> {
implements ResponseBodyAdvice<Object> {
@Autowired @Autowired
private MvcEndpoints endpoints; private MvcEndpoints endpoints;
@ -170,13 +163,11 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@PostConstruct @PostConstruct
public void init() { public void init() {
this.linksEnhancer = new LinksEnhancer(this.management.getContextPath(), this.linksEnhancer = new LinksEnhancer(this.management.getContextPath(), this.endpoints);
this.endpoints);
} }
@Override @Override
public boolean supports(MethodParameter returnType, public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
Class<? extends HttpMessageConverter<?>> converterType) {
returnType.increaseNestingLevel(); returnType.increaseNestingLevel();
Type nestedType = returnType.getNestedGenericParameterType(); Type nestedType = returnType.getNestedGenericParameterType();
returnType.decreaseNestingLevel(); returnType.decreaseNestingLevel();
@ -185,10 +176,9 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
} }
@Override @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpResponse response) {
ServerHttpRequest request, ServerHttpResponse response) {
if (request instanceof ServletServerHttpRequest) { if (request instanceof ServletServerHttpRequest) {
beforeBodyWrite(body, (ServletServerHttpRequest) request); beforeBodyWrite(body, (ServletServerHttpRequest) request);
} }
@ -205,15 +195,13 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
private void beforeBodyWrite(String path, ResourceSupport body) { private void beforeBodyWrite(String path, ResourceSupport body) {
if (isActuatorEndpointPath(path)) { if (isActuatorEndpointPath(path)) {
this.linksEnhancer.addEndpointLinks(body, this.linksEnhancer.addEndpointLinks(body, this.halJsonMvcEndpoint.getPath());
this.halJsonMvcEndpoint.getPath());
} }
} }
private boolean isActuatorEndpointPath(String path) { private boolean isActuatorEndpointPath(String path) {
if (this.halJsonMvcEndpoint != null) { if (this.halJsonMvcEndpoint != null) {
String toMatch = this.management.getContextPath() String toMatch = this.management.getContextPath() + this.halJsonMvcEndpoint.getPath();
+ this.halJsonMvcEndpoint.getPath();
return toMatch.equals(path) || (toMatch + "/").equals(path); return toMatch.equals(path) || (toMatch + "/").equals(path);
} }
return false; return false;
@ -227,8 +215,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
* could not be enhanced (e.g. "/env/{name}") because their values are "primitive" are * could not be enhanced (e.g. "/env/{name}") because their values are "primitive" are
* ignored. * ignored.
*/ */
@ConditionalOnProperty(prefix = "endpoints.hypermedia", name = "enabled", @ConditionalOnProperty(prefix = "endpoints.hypermedia", name = "enabled", matchIfMissing = false)
matchIfMissing = false)
@ControllerAdvice(assignableTypes = MvcEndpoint.class) @ControllerAdvice(assignableTypes = MvcEndpoint.class)
static class MvcEndpointAdvice implements ResponseBodyAdvice<Object> { static class MvcEndpointAdvice implements ResponseBodyAdvice<Object> {
@ -243,48 +230,41 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@PostConstruct @PostConstruct
public void configureHttpMessageConverters() { public void configureHttpMessageConverters() {
for (RequestMappingHandlerAdapter handlerAdapter : this.handlerAdapters) { for (RequestMappingHandlerAdapter handlerAdapter : this.handlerAdapters) {
for (HttpMessageConverter<?> messageConverter : handlerAdapter for (HttpMessageConverter<?> messageConverter : handlerAdapter.getMessageConverters()) {
.getMessageConverters()) {
configureHttpMessageConverter(messageConverter); configureHttpMessageConverter(messageConverter);
} }
} }
} }
private void configureHttpMessageConverter( private void configureHttpMessageConverter(HttpMessageConverter<?> messageConverter) {
HttpMessageConverter<?> messageConverter) {
if (messageConverter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) { if (messageConverter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) {
List<MediaType> supportedMediaTypes = new ArrayList<MediaType>( List<MediaType> supportedMediaTypes = new ArrayList<MediaType>(
messageConverter.getSupportedMediaTypes()); messageConverter.getSupportedMediaTypes());
supportedMediaTypes.add(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON); supportedMediaTypes.add(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON);
((AbstractHttpMessageConverter<?>) messageConverter) ((AbstractHttpMessageConverter<?>) messageConverter).setSupportedMediaTypes(supportedMediaTypes);
.setSupportedMediaTypes(supportedMediaTypes);
} }
} }
@Override @Override
public boolean supports(MethodParameter returnType, public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
Class<? extends HttpMessageConverter<?>> converterType) {
Class<?> controllerType = returnType.getDeclaringClass(); Class<?> controllerType = returnType.getDeclaringClass();
return !HalJsonMvcEndpoint.class.isAssignableFrom(controllerType); return !HalJsonMvcEndpoint.class.isAssignableFrom(controllerType);
} }
@Override @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpResponse response) {
ServerHttpRequest request, ServerHttpResponse response) {
if (request instanceof ServletServerHttpRequest) { if (request instanceof ServletServerHttpRequest) {
return beforeBodyWrite(body, returnType, selectedContentType, return beforeBodyWrite(body, returnType, selectedContentType, selectedConverterType,
selectedConverterType, (ServletServerHttpRequest) request, (ServletServerHttpRequest) request, response);
response);
} }
return body; return body;
} }
private Object beforeBodyWrite(Object body, MethodParameter returnType, private Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServletServerHttpRequest request,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpResponse response) {
ServletServerHttpRequest request, ServerHttpResponse response) {
if (body == null || body instanceof Resource) { if (body == null || body instanceof Resource) {
// Assume it already was handled or it already has its links // Assume it already was handled or it already has its links
return body; return body;
@ -293,16 +273,14 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
// We can't add links to a collection without wrapping it // We can't add links to a collection without wrapping it
return body; return body;
} }
HttpMessageConverter<Object> converter = findConverter(selectedConverterType, HttpMessageConverter<Object> converter = findConverter(selectedConverterType, selectedContentType);
selectedContentType);
if (converter == null || isHypermediaDisabled(returnType)) { if (converter == null || isHypermediaDisabled(returnType)) {
// Not a resource that can be enhanced with a link // Not a resource that can be enhanced with a link
return body; return body;
} }
String path = getPath(request); String path = getPath(request);
try { try {
converter.write(new EndpointResource(body, path), selectedContentType, converter.write(new EndpointResource(body, path), selectedContentType, response);
response);
} }
catch (IOException ex) { catch (IOException ex) {
throw new HttpMessageNotWritableException("Cannot write response", ex); throw new HttpMessageNotWritableException("Cannot write response", ex);
@ -312,16 +290,13 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private HttpMessageConverter<Object> findConverter( private HttpMessageConverter<Object> findConverter(
Class<? extends HttpMessageConverter<?>> selectedConverterType, Class<? extends HttpMessageConverter<?>> selectedConverterType, MediaType mediaType) {
MediaType mediaType) { HttpMessageConverter<Object> cached = (HttpMessageConverter<Object>) this.converterCache.get(mediaType);
HttpMessageConverter<Object> cached = (HttpMessageConverter<Object>) this.converterCache
.get(mediaType);
if (cached != null) { if (cached != null) {
return cached; return cached;
} }
for (RequestMappingHandlerAdapter handlerAdapter : this.handlerAdapters) { for (RequestMappingHandlerAdapter handlerAdapter : this.handlerAdapters) {
for (HttpMessageConverter<?> converter : handlerAdapter for (HttpMessageConverter<?> converter : handlerAdapter.getMessageConverters()) {
.getMessageConverters()) {
if (selectedConverterType.isAssignableFrom(converter.getClass()) if (selectedConverterType.isAssignableFrom(converter.getClass())
&& converter.canWrite(EndpointResource.class, mediaType)) { && converter.canWrite(EndpointResource.class, mediaType)) {
this.converterCache.put(mediaType, converter); this.converterCache.put(mediaType, converter);
@ -333,10 +308,8 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
} }
private boolean isHypermediaDisabled(MethodParameter returnType) { private boolean isHypermediaDisabled(MethodParameter returnType) {
return AnnotationUtils.findAnnotation(returnType.getMethod(), return AnnotationUtils.findAnnotation(returnType.getMethod(), HypermediaDisabled.class) != null
HypermediaDisabled.class) != null || AnnotationUtils.findAnnotation(returnType.getMethod().getDeclaringClass(),
|| AnnotationUtils.findAnnotation(
returnType.getMethod().getDeclaringClass(),
HypermediaDisabled.class) != null; HypermediaDisabled.class) != null;
} }
@ -359,8 +332,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
EndpointResource(Object content, String path) { EndpointResource(Object content, String path) {
this.content = (content instanceof Map) ? null : content; this.content = (content instanceof Map) ? null : content;
this.embedded = (Map<String, Object>) ((this.content != null) ? null this.embedded = (Map<String, Object>) ((this.content != null) ? null : content);
: content);
add(linkTo(Object.class).slash(path).withSelfRel()); add(linkTo(Object.class).slash(path).withSelfRel());
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -67,8 +67,7 @@ import org.springframework.web.cors.CorsConfiguration;
* @since 1.3.0 * @since 1.3.0
*/ */
@ManagementContextConfiguration @ManagementContextConfiguration
@EnableConfigurationProperties({ HealthMvcEndpointProperties.class, @EnableConfigurationProperties({ HealthMvcEndpointProperties.class, EndpointCorsProperties.class })
EndpointCorsProperties.class })
public class EndpointWebMvcManagementContextConfiguration { public class EndpointWebMvcManagementContextConfiguration {
private final HealthMvcEndpointProperties healthMvcEndpointProperties; private final HealthMvcEndpointProperties healthMvcEndpointProperties;
@ -79,16 +78,13 @@ public class EndpointWebMvcManagementContextConfiguration {
private final List<EndpointHandlerMappingCustomizer> mappingCustomizers; private final List<EndpointHandlerMappingCustomizer> mappingCustomizers;
public EndpointWebMvcManagementContextConfiguration( public EndpointWebMvcManagementContextConfiguration(HealthMvcEndpointProperties healthMvcEndpointProperties,
HealthMvcEndpointProperties healthMvcEndpointProperties, ManagementServerProperties managementServerProperties, EndpointCorsProperties corsProperties,
ManagementServerProperties managementServerProperties,
EndpointCorsProperties corsProperties,
ObjectProvider<List<EndpointHandlerMappingCustomizer>> mappingCustomizers) { ObjectProvider<List<EndpointHandlerMappingCustomizer>> mappingCustomizers) {
this.healthMvcEndpointProperties = healthMvcEndpointProperties; this.healthMvcEndpointProperties = healthMvcEndpointProperties;
this.managementServerProperties = managementServerProperties; this.managementServerProperties = managementServerProperties;
this.corsProperties = corsProperties; this.corsProperties = corsProperties;
List<EndpointHandlerMappingCustomizer> providedCustomizers = mappingCustomizers List<EndpointHandlerMappingCustomizer> providedCustomizers = mappingCustomizers.getIfAvailable();
.getIfAvailable();
this.mappingCustomizers = (providedCustomizers != null) ? providedCustomizers this.mappingCustomizers = (providedCustomizers != null) ? providedCustomizers
: Collections.<EndpointHandlerMappingCustomizer>emptyList(); : Collections.<EndpointHandlerMappingCustomizer>emptyList();
} }
@ -98,8 +94,7 @@ public class EndpointWebMvcManagementContextConfiguration {
public EndpointHandlerMapping endpointHandlerMapping() { public EndpointHandlerMapping endpointHandlerMapping() {
Set<MvcEndpoint> endpoints = mvcEndpoints().getEndpoints(); Set<MvcEndpoint> endpoints = mvcEndpoints().getEndpoints();
CorsConfiguration corsConfiguration = getCorsConfiguration(this.corsProperties); CorsConfiguration corsConfiguration = getCorsConfiguration(this.corsProperties);
EndpointHandlerMapping mapping = new EndpointHandlerMapping(endpoints, EndpointHandlerMapping mapping = new EndpointHandlerMapping(endpoints, corsConfiguration);
corsConfiguration);
mapping.setPrefix(this.managementServerProperties.getContextPath()); mapping.setPrefix(this.managementServerProperties.getContextPath());
MvcEndpointSecurityInterceptor securityInterceptor = new MvcEndpointSecurityInterceptor( MvcEndpointSecurityInterceptor securityInterceptor = new MvcEndpointSecurityInterceptor(
this.managementServerProperties.getSecurity().isEnabled(), this.managementServerProperties.getSecurity().isEnabled(),
@ -166,8 +161,7 @@ public class EndpointWebMvcManagementContextConfiguration {
this.managementServerProperties.getSecurity().isEnabled(), this.managementServerProperties.getSecurity().isEnabled(),
managementServerProperties.getSecurity().getRoles()); managementServerProperties.getSecurity().getRoles());
if (this.healthMvcEndpointProperties.getMapping() != null) { if (this.healthMvcEndpointProperties.getMapping() != null) {
healthMvcEndpoint healthMvcEndpoint.addStatusMapping(this.healthMvcEndpointProperties.getMapping());
.addStatusMapping(this.healthMvcEndpointProperties.getMapping());
} }
return healthMvcEndpoint; return healthMvcEndpoint;
} }
@ -208,33 +202,27 @@ public class EndpointWebMvcManagementContextConfiguration {
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnBean(AuditEventRepository.class) @ConditionalOnBean(AuditEventRepository.class)
@ConditionalOnEnabledEndpoint("auditevents") @ConditionalOnEnabledEndpoint("auditevents")
public AuditEventsMvcEndpoint auditEventMvcEndpoint( public AuditEventsMvcEndpoint auditEventMvcEndpoint(AuditEventRepository auditEventRepository) {
AuditEventRepository auditEventRepository) {
return new AuditEventsMvcEndpoint(auditEventRepository); return new AuditEventsMvcEndpoint(auditEventRepository);
} }
private static class LogFileCondition extends SpringBootCondition { private static class LogFileCondition extends SpringBootCondition {
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment(); Environment environment = context.getEnvironment();
String config = environment.resolvePlaceholders("${logging.file:}"); String config = environment.resolvePlaceholders("${logging.file:}");
ConditionMessage.Builder message = ConditionMessage.forCondition("Log File"); ConditionMessage.Builder message = ConditionMessage.forCondition("Log File");
if (StringUtils.hasText(config)) { if (StringUtils.hasText(config)) {
return ConditionOutcome return ConditionOutcome.match(message.found("logging.file").items(config));
.match(message.found("logging.file").items(config));
} }
config = environment.resolvePlaceholders("${logging.path:}"); config = environment.resolvePlaceholders("${logging.path:}");
if (StringUtils.hasText(config)) { if (StringUtils.hasText(config)) {
return ConditionOutcome return ConditionOutcome.match(message.found("logging.path").items(config));
.match(message.found("logging.path").items(config));
} }
config = new RelaxedPropertyResolver(environment, "endpoints.logfile.") config = new RelaxedPropertyResolver(environment, "endpoints.logfile.").getProperty("external-file");
.getProperty("external-file");
if (StringUtils.hasText(config)) { if (StringUtils.hasText(config)) {
return ConditionOutcome.match( return ConditionOutcome.match(message.found("endpoints.logfile.external-file").items(config));
message.found("endpoints.logfile.external-file").items(config));
} }
return ConditionOutcome.noMatch(message.didNotFind("logging file").atAll()); return ConditionOutcome.noMatch(message.didNotFind("logging file").atAll());
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,8 +33,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
* @since 1.3.0 * @since 1.3.0
*/ */
@Qualifier @Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@Documented @Documented

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,8 +33,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
* @since 1.3.0 * @since 1.3.0
*/ */
@Qualifier @Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@Documented @Documented

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -97,16 +97,13 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
@Configuration @Configuration
@AutoConfigureBefore({ EndpointAutoConfiguration.class }) @AutoConfigureBefore({ EndpointAutoConfiguration.class })
@AutoConfigureAfter({ ActiveMQAutoConfiguration.class, CassandraAutoConfiguration.class, @AutoConfigureAfter({ ActiveMQAutoConfiguration.class, CassandraAutoConfiguration.class,
CassandraDataAutoConfiguration.class, CouchbaseDataAutoConfiguration.class, CassandraDataAutoConfiguration.class, CouchbaseDataAutoConfiguration.class, DataSourceAutoConfiguration.class,
DataSourceAutoConfiguration.class, ElasticsearchAutoConfiguration.class, ElasticsearchAutoConfiguration.class, JestAutoConfiguration.class, JmsAutoConfiguration.class,
JestAutoConfiguration.class, JmsAutoConfiguration.class, LdapDataAutoConfiguration.class, MailSenderAutoConfiguration.class, MongoAutoConfiguration.class,
LdapDataAutoConfiguration.class, MailSenderAutoConfiguration.class, MongoDataAutoConfiguration.class, RabbitAutoConfiguration.class, RedisAutoConfiguration.class,
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
RabbitAutoConfiguration.class, RedisAutoConfiguration.class,
SolrAutoConfiguration.class }) SolrAutoConfiguration.class })
@EnableConfigurationProperties({ HealthIndicatorProperties.class }) @EnableConfigurationProperties({ HealthIndicatorProperties.class })
@Import({ @Import({ ElasticsearchHealthIndicatorConfiguration.ElasticsearchClientHealthIndicatorConfiguration.class,
ElasticsearchHealthIndicatorConfiguration.ElasticsearchClientHealthIndicatorConfiguration.class,
ElasticsearchHealthIndicatorConfiguration.ElasticsearchJestHealthIndicatorConfiguration.class }) ElasticsearchHealthIndicatorConfiguration.ElasticsearchJestHealthIndicatorConfiguration.class })
public class HealthIndicatorAutoConfiguration { public class HealthIndicatorAutoConfiguration {
@ -136,13 +133,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass({ CassandraOperations.class, Cluster.class }) @ConditionalOnClass({ CassandraOperations.class, Cluster.class })
@ConditionalOnBean(CassandraOperations.class) @ConditionalOnBean(CassandraOperations.class)
@ConditionalOnEnabledHealthIndicator("cassandra") @ConditionalOnEnabledHealthIndicator("cassandra")
public static class CassandraHealthIndicatorConfiguration extends public static class CassandraHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<CassandraHealthIndicator, CassandraOperations> { extends CompositeHealthIndicatorConfiguration<CassandraHealthIndicator, CassandraOperations> {
private final Map<String, CassandraOperations> cassandraOperations; private final Map<String, CassandraOperations> cassandraOperations;
public CassandraHealthIndicatorConfiguration( public CassandraHealthIndicatorConfiguration(Map<String, CassandraOperations> cassandraOperations) {
Map<String, CassandraOperations> cassandraOperations) {
this.cassandraOperations = cassandraOperations; this.cassandraOperations = cassandraOperations;
} }
@ -158,13 +154,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass({ CouchbaseOperations.class, Bucket.class }) @ConditionalOnClass({ CouchbaseOperations.class, Bucket.class })
@ConditionalOnBean(CouchbaseOperations.class) @ConditionalOnBean(CouchbaseOperations.class)
@ConditionalOnEnabledHealthIndicator("couchbase") @ConditionalOnEnabledHealthIndicator("couchbase")
public static class CouchbaseHealthIndicatorConfiguration extends public static class CouchbaseHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<CouchbaseHealthIndicator, CouchbaseOperations> { extends CompositeHealthIndicatorConfiguration<CouchbaseHealthIndicator, CouchbaseOperations> {
private final Map<String, CouchbaseOperations> couchbaseOperations; private final Map<String, CouchbaseOperations> couchbaseOperations;
public CouchbaseHealthIndicatorConfiguration( public CouchbaseHealthIndicatorConfiguration(Map<String, CouchbaseOperations> couchbaseOperations) {
Map<String, CouchbaseOperations> couchbaseOperations) {
this.couchbaseOperations = couchbaseOperations; this.couchbaseOperations = couchbaseOperations;
} }
@ -181,8 +176,7 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnBean(DataSource.class) @ConditionalOnBean(DataSource.class)
@ConditionalOnEnabledHealthIndicator("db") @ConditionalOnEnabledHealthIndicator("db")
public static class DataSourcesHealthIndicatorConfiguration extends public static class DataSourcesHealthIndicatorConfiguration extends
CompositeHealthIndicatorConfiguration<DataSourceHealthIndicator, DataSource> CompositeHealthIndicatorConfiguration<DataSourceHealthIndicator, DataSource> implements InitializingBean {
implements InitializingBean {
private final Map<String, DataSource> dataSources; private final Map<String, DataSource> dataSources;
@ -190,15 +184,13 @@ public class HealthIndicatorAutoConfiguration {
private DataSourcePoolMetadataProvider poolMetadataProvider; private DataSourcePoolMetadataProvider poolMetadataProvider;
public DataSourcesHealthIndicatorConfiguration( public DataSourcesHealthIndicatorConfiguration(ObjectProvider<Map<String, DataSource>> dataSources,
ObjectProvider<Map<String, DataSource>> dataSources,
ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders) { ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders) {
this.dataSources = filterDataSources(dataSources.getIfAvailable()); this.dataSources = filterDataSources(dataSources.getIfAvailable());
this.metadataProviders = metadataProviders.getIfAvailable(); this.metadataProviders = metadataProviders.getIfAvailable();
} }
private Map<String, DataSource> filterDataSources( private Map<String, DataSource> filterDataSources(Map<String, DataSource> candidates) {
Map<String, DataSource> candidates) {
if (candidates == null) { if (candidates == null) {
return null; return null;
} }
@ -213,8 +205,7 @@ public class HealthIndicatorAutoConfiguration {
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
this.poolMetadataProvider = new DataSourcePoolMetadataProviders( this.poolMetadataProvider = new DataSourcePoolMetadataProviders(this.metadataProviders);
this.metadataProviders);
} }
@Bean @Bean
@ -229,8 +220,7 @@ public class HealthIndicatorAutoConfiguration {
} }
private String getValidationQuery(DataSource source) { private String getValidationQuery(DataSource source) {
DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider.getDataSourcePoolMetadata(source);
.getDataSourcePoolMetadata(source);
return (poolMetadata != null) ? poolMetadata.getValidationQuery() : null; return (poolMetadata != null) ? poolMetadata.getValidationQuery() : null;
} }
@ -240,13 +230,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(LdapOperations.class) @ConditionalOnClass(LdapOperations.class)
@ConditionalOnBean(LdapOperations.class) @ConditionalOnBean(LdapOperations.class)
@ConditionalOnEnabledHealthIndicator("ldap") @ConditionalOnEnabledHealthIndicator("ldap")
public static class LdapHealthIndicatorConfiguration extends public static class LdapHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<LdapHealthIndicator, LdapOperations> { extends CompositeHealthIndicatorConfiguration<LdapHealthIndicator, LdapOperations> {
private final Map<String, LdapOperations> ldapOperations; private final Map<String, LdapOperations> ldapOperations;
public LdapHealthIndicatorConfiguration( public LdapHealthIndicatorConfiguration(Map<String, LdapOperations> ldapOperations) {
Map<String, LdapOperations> ldapOperations) {
this.ldapOperations = ldapOperations; this.ldapOperations = ldapOperations;
} }
@ -262,13 +251,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(MongoTemplate.class) @ConditionalOnClass(MongoTemplate.class)
@ConditionalOnBean(MongoTemplate.class) @ConditionalOnBean(MongoTemplate.class)
@ConditionalOnEnabledHealthIndicator("mongo") @ConditionalOnEnabledHealthIndicator("mongo")
public static class MongoHealthIndicatorConfiguration extends public static class MongoHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<MongoHealthIndicator, MongoTemplate> { extends CompositeHealthIndicatorConfiguration<MongoHealthIndicator, MongoTemplate> {
private final Map<String, MongoTemplate> mongoTemplates; private final Map<String, MongoTemplate> mongoTemplates;
public MongoHealthIndicatorConfiguration( public MongoHealthIndicatorConfiguration(Map<String, MongoTemplate> mongoTemplates) {
Map<String, MongoTemplate> mongoTemplates) {
this.mongoTemplates = mongoTemplates; this.mongoTemplates = mongoTemplates;
} }
@ -284,13 +272,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(RedisConnectionFactory.class) @ConditionalOnClass(RedisConnectionFactory.class)
@ConditionalOnBean(RedisConnectionFactory.class) @ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnEnabledHealthIndicator("redis") @ConditionalOnEnabledHealthIndicator("redis")
public static class RedisHealthIndicatorConfiguration extends public static class RedisHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<RedisHealthIndicator, RedisConnectionFactory> { extends CompositeHealthIndicatorConfiguration<RedisHealthIndicator, RedisConnectionFactory> {
private final Map<String, RedisConnectionFactory> redisConnectionFactories; private final Map<String, RedisConnectionFactory> redisConnectionFactories;
public RedisHealthIndicatorConfiguration( public RedisHealthIndicatorConfiguration(Map<String, RedisConnectionFactory> redisConnectionFactories) {
Map<String, RedisConnectionFactory> redisConnectionFactories) {
this.redisConnectionFactories = redisConnectionFactories; this.redisConnectionFactories = redisConnectionFactories;
} }
@ -306,13 +293,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(RabbitTemplate.class) @ConditionalOnClass(RabbitTemplate.class)
@ConditionalOnBean(RabbitTemplate.class) @ConditionalOnBean(RabbitTemplate.class)
@ConditionalOnEnabledHealthIndicator("rabbit") @ConditionalOnEnabledHealthIndicator("rabbit")
public static class RabbitHealthIndicatorConfiguration extends public static class RabbitHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<RabbitHealthIndicator, RabbitTemplate> { extends CompositeHealthIndicatorConfiguration<RabbitHealthIndicator, RabbitTemplate> {
private final Map<String, RabbitTemplate> rabbitTemplates; private final Map<String, RabbitTemplate> rabbitTemplates;
public RabbitHealthIndicatorConfiguration( public RabbitHealthIndicatorConfiguration(Map<String, RabbitTemplate> rabbitTemplates) {
Map<String, RabbitTemplate> rabbitTemplates) {
this.rabbitTemplates = rabbitTemplates; this.rabbitTemplates = rabbitTemplates;
} }
@ -328,8 +314,8 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(SolrClient.class) @ConditionalOnClass(SolrClient.class)
@ConditionalOnBean(SolrClient.class) @ConditionalOnBean(SolrClient.class)
@ConditionalOnEnabledHealthIndicator("solr") @ConditionalOnEnabledHealthIndicator("solr")
public static class SolrHealthIndicatorConfiguration extends public static class SolrHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<SolrHealthIndicator, SolrClient> { extends CompositeHealthIndicatorConfiguration<SolrHealthIndicator, SolrClient> {
private final Map<String, SolrClient> solrClients; private final Map<String, SolrClient> solrClients;
@ -351,8 +337,7 @@ public class HealthIndicatorAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(name = "diskSpaceHealthIndicator") @ConditionalOnMissingBean(name = "diskSpaceHealthIndicator")
public DiskSpaceHealthIndicator diskSpaceHealthIndicator( public DiskSpaceHealthIndicator diskSpaceHealthIndicator(DiskSpaceHealthIndicatorProperties properties) {
DiskSpaceHealthIndicatorProperties properties) {
return new DiskSpaceHealthIndicator(properties); return new DiskSpaceHealthIndicator(properties);
} }
@ -367,13 +352,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(JavaMailSenderImpl.class) @ConditionalOnClass(JavaMailSenderImpl.class)
@ConditionalOnBean(JavaMailSenderImpl.class) @ConditionalOnBean(JavaMailSenderImpl.class)
@ConditionalOnEnabledHealthIndicator("mail") @ConditionalOnEnabledHealthIndicator("mail")
public static class MailHealthIndicatorConfiguration extends public static class MailHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<MailHealthIndicator, JavaMailSenderImpl> { extends CompositeHealthIndicatorConfiguration<MailHealthIndicator, JavaMailSenderImpl> {
private final Map<String, JavaMailSenderImpl> mailSenders; private final Map<String, JavaMailSenderImpl> mailSenders;
public MailHealthIndicatorConfiguration( public MailHealthIndicatorConfiguration(ObjectProvider<Map<String, JavaMailSenderImpl>> mailSenders) {
ObjectProvider<Map<String, JavaMailSenderImpl>> mailSenders) {
this.mailSenders = mailSenders.getIfAvailable(); this.mailSenders = mailSenders.getIfAvailable();
} }
@ -389,13 +373,12 @@ public class HealthIndicatorAutoConfiguration {
@ConditionalOnClass(ConnectionFactory.class) @ConditionalOnClass(ConnectionFactory.class)
@ConditionalOnBean(ConnectionFactory.class) @ConditionalOnBean(ConnectionFactory.class)
@ConditionalOnEnabledHealthIndicator("jms") @ConditionalOnEnabledHealthIndicator("jms")
public static class JmsHealthIndicatorConfiguration extends public static class JmsHealthIndicatorConfiguration
CompositeHealthIndicatorConfiguration<JmsHealthIndicator, ConnectionFactory> { extends CompositeHealthIndicatorConfiguration<JmsHealthIndicator, ConnectionFactory> {
private final Map<String, ConnectionFactory> connectionFactories; private final Map<String, ConnectionFactory> connectionFactories;
public JmsHealthIndicatorConfiguration( public JmsHealthIndicatorConfiguration(ObjectProvider<Map<String, ConnectionFactory>> connectionFactories) {
ObjectProvider<Map<String, ConnectionFactory>> connectionFactories) {
this.connectionFactories = connectionFactories.getIfAvailable(); this.connectionFactories = connectionFactories.getIfAvailable();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,8 +63,7 @@ public class InfoContributorAutoConfiguration {
@Bean @Bean
@ConditionalOnEnabledInfoContributor("env") @ConditionalOnEnabledInfoContributor("env")
@Order(DEFAULT_ORDER) @Order(DEFAULT_ORDER)
public EnvironmentInfoContributor envInfoContributor( public EnvironmentInfoContributor envInfoContributor(ConfigurableEnvironment environment) {
ConfigurableEnvironment environment) {
return new EnvironmentInfoContributor(environment); return new EnvironmentInfoContributor(environment);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -95,8 +95,7 @@ public class JolokiaAutoConfiguration {
static class JolokiaCondition extends SpringBootCondition { static class JolokiaCondition extends SpringBootCondition {
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) {
boolean endpointsEnabled = isEnabled(context, "endpoints.", true); boolean endpointsEnabled = isEnabled(context, "endpoints.", true);
ConditionMessage.Builder message = ConditionMessage.forCondition("Jolokia"); ConditionMessage.Builder message = ConditionMessage.forCondition("Jolokia");
if (isEnabled(context, "endpoints.jolokia.", endpointsEnabled)) { if (isEnabled(context, "endpoints.jolokia.", endpointsEnabled)) {
@ -105,10 +104,8 @@ public class JolokiaAutoConfiguration {
return ConditionOutcome.noMatch(message.because("not enabled")); return ConditionOutcome.noMatch(message.because("not enabled"));
} }
private boolean isEnabled(ConditionContext context, String prefix, private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
boolean defaultValue) { RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
context.getEnvironment(), prefix);
return resolver.getProperty("enabled", Boolean.class, defaultValue); return resolver.getProperty("enabled", Boolean.class, defaultValue);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -47,8 +47,7 @@ class LinksEnhancer {
public void addEndpointLinks(ResourceSupport resource, String self) { public void addEndpointLinks(ResourceSupport resource, String self) {
if (!resource.hasLink("self")) { if (!resource.hasLink("self")) {
resource.add(linkTo(LinksEnhancer.class).slash(this.rootPath + self) resource.add(linkTo(LinksEnhancer.class).slash(this.rootPath + self).withSelfRel());
.withSelfRel());
} }
MultiValueMap<String, String> added = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> added = new LinkedMultiValueMap<String, String>();
for (MvcEndpoint endpoint : this.endpoints.getEndpoints()) { for (MvcEndpoint endpoint : this.endpoints.getEndpoints()) {
@ -71,8 +70,7 @@ class LinksEnhancer {
return (path.startsWith("/") ? path.substring(1) : path); return (path.startsWith("/") ? path.substring(1) : path);
} }
private void addEndpointLink(ResourceSupport resource, MvcEndpoint endpoint, private void addEndpointLink(ResourceSupport resource, MvcEndpoint endpoint, String rel) {
String rel) {
Class<?> type = endpoint.getEndpointType(); Class<?> type = endpoint.getEndpointType();
type = (type != null) ? type : Object.class; type = (type != null) ? type : Object.class;
if (StringUtils.hasText(rel)) { if (StringUtils.hasText(rel)) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,8 +32,7 @@ import org.springframework.beans.factory.annotation.Value;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.4.0 * @since 1.4.0
*/ */
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Value("${local.management.port}") @Value("${local.management.port}")

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,8 +43,7 @@ import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
* @see ManagementContextConfiguration * @see ManagementContextConfiguration
*/ */
@Order(Ordered.LOWEST_PRECEDENCE) @Order(Ordered.LOWEST_PRECEDENCE)
class ManagementContextConfigurationsImportSelector class ManagementContextConfigurationsImportSelector implements DeferredImportSelector, BeanClassLoaderAware {
implements DeferredImportSelector, BeanClassLoaderAware {
private ClassLoader classLoader; private ClassLoader classLoader;
@ -61,8 +60,7 @@ class ManagementContextConfigurationsImportSelector
} }
private List<ManagementConfiguration> getConfigurations() { private List<ManagementConfiguration> getConfigurations() {
SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory( SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory(this.classLoader);
this.classLoader);
List<ManagementConfiguration> configurations = new ArrayList<ManagementConfiguration>(); List<ManagementConfiguration> configurations = new ArrayList<ManagementConfiguration>();
for (String className : loadFactoryNames()) { for (String className : loadFactoryNames()) {
getConfiguration(readerFactory, configurations, className); getConfiguration(readerFactory, configurations, className);
@ -77,14 +75,12 @@ class ManagementContextConfigurationsImportSelector
configurations.add(new ManagementConfiguration(metadataReader)); configurations.add(new ManagementConfiguration(metadataReader));
} }
catch (IOException ex) { catch (IOException ex) {
throw new RuntimeException( throw new RuntimeException("Failed to read annotation metadata for '" + className + "'", ex);
"Failed to read annotation metadata for '" + className + "'", ex);
} }
} }
protected List<String> loadFactoryNames() { protected List<String> loadFactoryNames() {
return SpringFactoriesLoader return SpringFactoriesLoader.loadFactoryNames(ManagementContextConfiguration.class, this.classLoader);
.loadFactoryNames(ManagementContextConfiguration.class, this.classLoader);
} }
@Override @Override
@ -102,17 +98,14 @@ class ManagementContextConfigurationsImportSelector
private final int order; private final int order;
ManagementConfiguration(MetadataReader metadataReader) { ManagementConfiguration(MetadataReader metadataReader) {
AnnotationMetadata annotationMetadata = metadataReader AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
.getAnnotationMetadata();
this.order = readOrder(annotationMetadata); this.order = readOrder(annotationMetadata);
this.className = metadataReader.getClassMetadata().getClassName(); this.className = metadataReader.getClassMetadata().getClassName();
} }
private int readOrder(AnnotationMetadata annotationMetadata) { private int readOrder(AnnotationMetadata annotationMetadata) {
Map<String, Object> attributes = annotationMetadata Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(Order.class.getName());
.getAnnotationAttributes(Order.class.getName()); Integer order = (attributes != null) ? (Integer) attributes.get("value") : null;
Integer order = (attributes != null) ? (Integer) attributes.get("value")
: null;
return (order != null) ? order : Ordered.LOWEST_PRECEDENCE; return (order != null) ? order : Ordered.LOWEST_PRECEDENCE;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -60,8 +60,7 @@ public class ManagementServerProperties implements SecurityPrerequisite {
* security for the rest of the application, use * security for the rest of the application, use
* {@code SecurityProperties.ACCESS_OVERRIDE_ORDER} instead. * {@code SecurityProperties.ACCESS_OVERRIDE_ORDER} instead.
*/ */
public static final int ACCESS_OVERRIDE_ORDER = ManagementServerProperties.BASIC_AUTH_ORDER public static final int ACCESS_OVERRIDE_ORDER = ManagementServerProperties.BASIC_AUTH_ORDER - 1;
- 1;
/** /**
* Management endpoint HTTP port. Use the same port as the application by default. * Management endpoint HTTP port. Use the same port as the application by default.
@ -169,8 +168,7 @@ public class ManagementServerProperties implements SecurityPrerequisite {
/** /**
* Comma-separated list of roles that can access the management endpoint. * Comma-separated list of roles that can access the management endpoint.
*/ */
private List<String> roles = new ArrayList<String>( private List<String> roles = new ArrayList<String>(Collections.singletonList("ACTUATOR"));
Collections.singletonList("ACTUATOR"));
/** /**
* Session creating policy for security use (always, never, if_required, * Session creating policy for security use (always, never, if_required,

@ -48,8 +48,7 @@ public class ManagementServerPropertiesAutoConfiguration {
// In case security auto configuration hasn't been included // In case security auto configuration hasn't been included
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnClass( @ConditionalOnClass(name = "org.springframework.security.config.annotation.web.configuration.EnableWebSecurity")
name = "org.springframework.security.config.annotation.web.configuration.EnableWebSecurity")
public SecurityProperties securityProperties() { public SecurityProperties securityProperties() {
return new SecurityProperties(); return new SecurityProperties();
} }

@ -94,15 +94,12 @@ public class ManagementWebSecurityAutoConfiguration {
private static final String[] NO_PATHS = new String[0]; private static final String[] NO_PATHS = new String[0];
private static final RequestMatcher MATCH_NONE = new NegatedRequestMatcher( private static final RequestMatcher MATCH_NONE = new NegatedRequestMatcher(AnyRequestMatcher.INSTANCE);
AnyRequestMatcher.INSTANCE);
@Bean @Bean
public IgnoredRequestCustomizer managementIgnoredRequestCustomizer( public IgnoredRequestCustomizer managementIgnoredRequestCustomizer(ManagementServerProperties management,
ManagementServerProperties management,
ObjectProvider<ManagementContextResolver> contextResolver) { ObjectProvider<ManagementContextResolver> contextResolver) {
return new ManagementIgnoredRequestCustomizer(management, return new ManagementIgnoredRequestCustomizer(management, contextResolver.getIfAvailable());
contextResolver.getIfAvailable());
} }
private class ManagementIgnoredRequestCustomizer implements IgnoredRequestCustomizer { private class ManagementIgnoredRequestCustomizer implements IgnoredRequestCustomizer {
@ -120,8 +117,7 @@ public class ManagementWebSecurityAutoConfiguration {
@Override @Override
public void customize(IgnoredRequestConfigurer configurer) { public void customize(IgnoredRequestConfigurer configurer) {
if (!this.management.getSecurity().isEnabled()) { if (!this.management.getSecurity().isEnabled()) {
RequestMatcher requestMatcher = LazyEndpointPathRequestMatcher RequestMatcher requestMatcher = LazyEndpointPathRequestMatcher.getRequestMatcher(this.contextResolver);
.getRequestMatcher(this.contextResolver);
configurer.requestMatchers(requestMatcher); configurer.requestMatchers(requestMatcher);
} }
@ -130,15 +126,13 @@ public class ManagementWebSecurityAutoConfiguration {
} }
@Configuration @Configuration
protected static class ManagementSecurityPropertiesConfiguration protected static class ManagementSecurityPropertiesConfiguration implements SecurityPrerequisite {
implements SecurityPrerequisite {
private final SecurityProperties securityProperties; private final SecurityProperties securityProperties;
private final ManagementServerProperties managementServerProperties; private final ManagementServerProperties managementServerProperties;
public ManagementSecurityPropertiesConfiguration( public ManagementSecurityPropertiesConfiguration(ObjectProvider<SecurityProperties> securityProperties,
ObjectProvider<SecurityProperties> securityProperties,
ObjectProvider<ManagementServerProperties> managementServerProperties) { ObjectProvider<ManagementServerProperties> managementServerProperties) {
this.securityProperties = securityProperties.getIfAvailable(); this.securityProperties = securityProperties.getIfAvailable();
this.managementServerProperties = managementServerProperties.getIfAvailable(); this.managementServerProperties = managementServerProperties.getIfAvailable();
@ -146,8 +140,7 @@ public class ManagementWebSecurityAutoConfiguration {
@PostConstruct @PostConstruct
public void init() { public void init() {
if (this.managementServerProperties != null if (this.managementServerProperties != null && this.securityProperties != null) {
&& this.securityProperties != null) {
this.securityProperties.getUser().getRole() this.securityProperties.getUser().getRole()
.addAll(this.managementServerProperties.getSecurity().getRoles()); .addAll(this.managementServerProperties.getSecurity().getRoles());
} }
@ -169,16 +162,11 @@ public class ManagementWebSecurityAutoConfiguration {
static class WebSecurityEnablerCondition extends SpringBootCondition { static class WebSecurityEnablerCondition extends SpringBootCondition {
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) { String managementEnabled = context.getEnvironment().getProperty("management.security.enabled", "true");
String managementEnabled = context.getEnvironment() String basicEnabled = context.getEnvironment().getProperty("security.basic.enabled", "true");
.getProperty("management.security.enabled", "true"); ConditionMessage.Builder message = ConditionMessage.forCondition("WebSecurityEnabled");
String basicEnabled = context.getEnvironment() if ("true".equalsIgnoreCase(managementEnabled) && !"true".equalsIgnoreCase(basicEnabled)) {
.getProperty("security.basic.enabled", "true");
ConditionMessage.Builder message = ConditionMessage
.forCondition("WebSecurityEnabled");
if ("true".equalsIgnoreCase(managementEnabled)
&& !"true".equalsIgnoreCase(basicEnabled)) {
return ConditionOutcome.match(message.because("security enabled")); return ConditionOutcome.match(message.because("security enabled"));
} }
return ConditionOutcome.noMatch(message.because("security disabled")); return ConditionOutcome.noMatch(message.because("security disabled"));
@ -188,11 +176,9 @@ public class ManagementWebSecurityAutoConfiguration {
@Configuration @Configuration
@ConditionalOnMissingBean({ ManagementWebSecurityConfigurerAdapter.class }) @ConditionalOnMissingBean({ ManagementWebSecurityConfigurerAdapter.class })
@ConditionalOnProperty(prefix = "management.security", name = "enabled", @ConditionalOnProperty(prefix = "management.security", name = "enabled", matchIfMissing = true)
matchIfMissing = true)
@Order(ManagementServerProperties.BASIC_AUTH_ORDER) @Order(ManagementServerProperties.BASIC_AUTH_ORDER)
protected static class ManagementWebSecurityConfigurerAdapter protected static class ManagementWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
extends WebSecurityConfigurerAdapter {
private final SecurityProperties security; private final SecurityProperties security;
@ -201,8 +187,7 @@ public class ManagementWebSecurityAutoConfiguration {
private final ManagementContextResolver contextResolver; private final ManagementContextResolver contextResolver;
public ManagementWebSecurityConfigurerAdapter(SecurityProperties security, public ManagementWebSecurityConfigurerAdapter(SecurityProperties security,
ManagementServerProperties management, ManagementServerProperties management, ObjectProvider<ManagementContextResolver> contextResolver) {
ObjectProvider<ManagementContextResolver> contextResolver) {
this.security = security; this.security = security;
this.management = management; this.management = management;
this.contextResolver = contextResolver.getIfAvailable(); this.contextResolver = contextResolver.getIfAvailable();
@ -226,16 +211,13 @@ public class ManagementWebSecurityAutoConfiguration {
http.httpBasic().authenticationEntryPoint(entryPoint).and().cors(); http.httpBasic().authenticationEntryPoint(entryPoint).and().cors();
// No cookies for management endpoints by default // No cookies for management endpoints by default
http.csrf().disable(); http.csrf().disable();
http.sessionManagement() http.sessionManagement().sessionCreationPolicy(
.sessionCreationPolicy(asSpringSecuritySessionCreationPolicy( asSpringSecuritySessionCreationPolicy(this.management.getSecurity().getSessions()));
this.management.getSecurity().getSessions())); SpringBootWebSecurityConfiguration.configureHeaders(http.headers(), this.security.getHeaders());
SpringBootWebSecurityConfiguration.configureHeaders(http.headers(),
this.security.getHeaders());
} }
} }
private SessionCreationPolicy asSpringSecuritySessionCreationPolicy( private SessionCreationPolicy asSpringSecuritySessionCreationPolicy(Enum<?> value) {
Enum<?> value) {
if (value == null) { if (value == null) {
return SessionCreationPolicy.STATELESS; return SessionCreationPolicy.STATELESS;
} }
@ -244,8 +226,7 @@ public class ManagementWebSecurityAutoConfiguration {
private RequestMatcher getRequestMatcher() { private RequestMatcher getRequestMatcher() {
if (this.management.getSecurity().isEnabled()) { if (this.management.getSecurity().isEnabled()) {
return LazyEndpointPathRequestMatcher return LazyEndpointPathRequestMatcher.getRequestMatcher(this.contextResolver);
.getRequestMatcher(this.contextResolver);
} }
return null; return null;
} }
@ -258,11 +239,11 @@ public class ManagementWebSecurityAutoConfiguration {
private void configurePermittedRequests( private void configurePermittedRequests(
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry requests) { ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry requests) {
requests.requestMatchers(new LazyEndpointPathRequestMatcher( requests.requestMatchers(new LazyEndpointPathRequestMatcher(this.contextResolver, EndpointPaths.SENSITIVE))
this.contextResolver, EndpointPaths.SENSITIVE)).authenticated(); .authenticated();
// Permit access to the non-sensitive endpoints // Permit access to the non-sensitive endpoints
requests.requestMatchers(new LazyEndpointPathRequestMatcher( requests.requestMatchers(
this.contextResolver, EndpointPaths.NON_SENSITIVE)).permitAll(); new LazyEndpointPathRequestMatcher(this.contextResolver, EndpointPaths.NON_SENSITIVE)).permitAll();
} }
} }
@ -324,27 +305,23 @@ public class ManagementWebSecurityAutoConfiguration {
private RequestMatcher delegate; private RequestMatcher delegate;
public static RequestMatcher getRequestMatcher( public static RequestMatcher getRequestMatcher(ManagementContextResolver contextResolver) {
ManagementContextResolver contextResolver) {
if (contextResolver == null) { if (contextResolver == null) {
return null; return null;
} }
ManagementServerProperties management = contextResolver ManagementServerProperties management = contextResolver.getApplicationContext()
.getApplicationContext().getBean(ManagementServerProperties.class); .getBean(ManagementServerProperties.class);
ServerProperties server = contextResolver.getApplicationContext() ServerProperties server = contextResolver.getApplicationContext().getBean(ServerProperties.class);
.getBean(ServerProperties.class);
String path = management.getContextPath(); String path = management.getContextPath();
if (StringUtils.hasText(path)) { if (StringUtils.hasText(path)) {
AntPathRequestMatcher matcher = new AntPathRequestMatcher( AntPathRequestMatcher matcher = new AntPathRequestMatcher(server.getPath(path) + "/**");
server.getPath(path) + "/**");
return matcher; return matcher;
} }
// Match everything, including the sensitive and non-sensitive paths // Match everything, including the sensitive and non-sensitive paths
return new LazyEndpointPathRequestMatcher(contextResolver, EndpointPaths.ALL); return new LazyEndpointPathRequestMatcher(contextResolver, EndpointPaths.ALL);
} }
LazyEndpointPathRequestMatcher(ManagementContextResolver contextResolver, LazyEndpointPathRequestMatcher(ManagementContextResolver contextResolver, EndpointPaths endpointPaths) {
EndpointPaths endpointPaths) {
this.contextResolver = contextResolver; this.contextResolver = contextResolver;
this.endpointPaths = endpointPaths; this.endpointPaths = endpointPaths;
} }
@ -358,8 +335,7 @@ public class ManagementWebSecurityAutoConfiguration {
} }
private RequestMatcher createDelegate() { private RequestMatcher createDelegate() {
ServerProperties server = this.contextResolver.getApplicationContext() ServerProperties server = this.contextResolver.getApplicationContext().getBean(ServerProperties.class);
.getBean(ServerProperties.class);
List<RequestMatcher> matchers = new ArrayList<RequestMatcher>(); List<RequestMatcher> matchers = new ArrayList<RequestMatcher>();
EndpointHandlerMapping endpointHandlerMapping = getRequiredEndpointHandlerMapping(); EndpointHandlerMapping endpointHandlerMapping = getRequiredEndpointHandlerMapping();
for (String path : this.endpointPaths.getPaths(endpointHandlerMapping)) { for (String path : this.endpointPaths.getPaths(endpointHandlerMapping)) {
@ -376,8 +352,7 @@ public class ManagementWebSecurityAutoConfiguration {
} }
if (endpointHandlerMapping == null) { if (endpointHandlerMapping == null) {
// Maybe there are actually no endpoints (e.g. management.port=-1) // Maybe there are actually no endpoints (e.g. management.port=-1)
endpointHandlerMapping = new EndpointHandlerMapping( endpointHandlerMapping = new EndpointHandlerMapping(Collections.<MvcEndpoint>emptySet());
Collections.<MvcEndpoint>emptySet());
} }
return endpointHandlerMapping; return endpointHandlerMapping;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -76,13 +76,11 @@ public class MetricExportAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(name = "metricWritersMetricExporter") @ConditionalOnMissingBean(name = "metricWritersMetricExporter")
public SchedulingConfigurer metricWritersMetricExporter( public SchedulingConfigurer metricWritersMetricExporter(MetricExportProperties properties) {
MetricExportProperties properties) {
Map<String, GaugeWriter> writers = new HashMap<String, GaugeWriter>(); Map<String, GaugeWriter> writers = new HashMap<String, GaugeWriter>();
MetricReader reader = this.endpointReader; MetricReader reader = this.endpointReader;
if (reader == null && !CollectionUtils.isEmpty(this.readers)) { if (reader == null && !CollectionUtils.isEmpty(this.readers)) {
reader = new CompositeMetricReader( reader = new CompositeMetricReader(this.readers.toArray(new MetricReader[this.readers.size()]));
this.readers.toArray(new MetricReader[this.readers.size()]));
} }
if (reader == null && CollectionUtils.isEmpty(this.exporters)) { if (reader == null && CollectionUtils.isEmpty(this.exporters)) {
return new NoOpSchedulingConfigurer(); return new NoOpSchedulingConfigurer();
@ -95,8 +93,7 @@ public class MetricExportAutoConfiguration {
exporters.setReader(reader); exporters.setReader(reader);
exporters.setWriters(writers); exporters.setWriters(writers);
} }
exporters.setExporters((this.exporters != null) ? this.exporters exporters.setExporters((this.exporters != null) ? this.exporters : Collections.<String, Exporter>emptyMap());
: Collections.<String, Exporter>emptyMap());
return exporters; return exporters;
} }
@ -109,8 +106,8 @@ public class MetricExportAutoConfiguration {
@ConditionalOnProperty(prefix = "spring.metrics.export.statsd", name = "host") @ConditionalOnProperty(prefix = "spring.metrics.export.statsd", name = "host")
public StatsdMetricWriter statsdMetricWriter(MetricExportProperties properties) { public StatsdMetricWriter statsdMetricWriter(MetricExportProperties properties) {
MetricExportProperties.Statsd statsdProperties = properties.getStatsd(); MetricExportProperties.Statsd statsdProperties = properties.getStatsd();
return new StatsdMetricWriter(statsdProperties.getPrefix(), return new StatsdMetricWriter(statsdProperties.getPrefix(), statsdProperties.getHost(),
statsdProperties.getHost(), statsdProperties.getPort()); statsdProperties.getPort());
} }
} }
@ -127,8 +124,7 @@ public class MetricExportAutoConfiguration {
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MetricExportProperties metricExportProperties() { public MetricExportProperties metricExportProperties() {
MetricExportProperties export = new MetricExportProperties(); MetricExportProperties export = new MetricExportProperties();
export.getRedis().setPrefix("spring.metrics" export.getRedis().setPrefix("spring.metrics" + ((this.prefix.length() > 0) ? "." : "") + this.prefix);
+ ((this.prefix.length() > 0) ? "." : "") + this.prefix);
export.getAggregate().setPrefix(this.prefix); export.getAggregate().setPrefix(this.prefix);
export.getAggregate().setKeyPattern(this.aggregateKeyPattern); export.getAggregate().setKeyPattern(this.aggregateKeyPattern);
return export; return export;

@ -43,11 +43,9 @@ import org.springframework.web.servlet.HandlerMapping;
*/ */
@Configuration @Configuration
@ConditionalOnBean({ CounterService.class, GaugeService.class }) @ConditionalOnBean({ CounterService.class, GaugeService.class })
@ConditionalOnClass({ Servlet.class, ServletRegistration.class, @ConditionalOnClass({ Servlet.class, ServletRegistration.class, OncePerRequestFilter.class, HandlerMapping.class })
OncePerRequestFilter.class, HandlerMapping.class })
@AutoConfigureAfter(MetricRepositoryAutoConfiguration.class) @AutoConfigureAfter(MetricRepositoryAutoConfiguration.class)
@ConditionalOnProperty(prefix = "endpoints.metrics.filter", name = "enabled", @ConditionalOnProperty(prefix = "endpoints.metrics.filter", name = "enabled", matchIfMissing = true)
matchIfMissing = true)
@EnableConfigurationProperties({ MetricFilterProperties.class }) @EnableConfigurationProperties({ MetricFilterProperties.class })
public class MetricFilterAutoConfiguration { public class MetricFilterAutoConfiguration {
@ -57,8 +55,8 @@ public class MetricFilterAutoConfiguration {
private final MetricFilterProperties properties; private final MetricFilterProperties properties;
public MetricFilterAutoConfiguration(CounterService counterService, public MetricFilterAutoConfiguration(CounterService counterService, GaugeService gaugeService,
GaugeService gaugeService, MetricFilterProperties properties) { MetricFilterProperties properties) {
this.counterService = counterService; this.counterService = counterService;
this.gaugeService = gaugeService; this.gaugeService = gaugeService;
this.properties = properties; this.properties = properties;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,10 +43,8 @@ public class MetricFilterProperties {
private Set<MetricsFilterSubmission> counterSubmissions; private Set<MetricsFilterSubmission> counterSubmissions;
public MetricFilterProperties() { public MetricFilterProperties() {
this.gaugeSubmissions = new HashSet<MetricsFilterSubmission>( this.gaugeSubmissions = new HashSet<MetricsFilterSubmission>(EnumSet.of(MetricsFilterSubmission.MERGED));
EnumSet.of(MetricsFilterSubmission.MERGED)); this.counterSubmissions = new HashSet<MetricsFilterSubmission>(EnumSet.of(MetricsFilterSubmission.MERGED));
this.counterSubmissions = new HashSet<MetricsFilterSubmission>(
EnumSet.of(MetricsFilterSubmission.MERGED));
} }
public Set<MetricsFilterSubmission> getGaugeSubmissions() { public Set<MetricsFilterSubmission> getGaugeSubmissions() {
@ -73,8 +71,7 @@ public class MetricFilterProperties {
return shouldSubmit(this.counterSubmissions, submission); return shouldSubmit(this.counterSubmissions, submission);
} }
private boolean shouldSubmit(Set<MetricsFilterSubmission> submissions, private boolean shouldSubmit(Set<MetricsFilterSubmission> submissions, MetricsFilterSubmission submission) {
MetricsFilterSubmission submission) {
return submissions != null && submissions.contains(submission); return submissions != null && submissions.contains(submission);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -124,8 +124,7 @@ public class MetricRepositoryAutoConfiguration {
@Bean @Bean
@ExportMetricReader @ExportMetricReader
@ConditionalOnMissingBean @ConditionalOnMissingBean
public BufferMetricReader actuatorMetricReader(CounterBuffers counters, public BufferMetricReader actuatorMetricReader(CounterBuffers counters, GaugeBuffers gauges) {
GaugeBuffers gauges) {
return new BufferMetricReader(counters, gauges); return new BufferMetricReader(counters, gauges);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,8 +43,7 @@ public class MetricsChannelAutoConfiguration {
@Bean @Bean
@ExportMetricWriter @ExportMetricWriter
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MessageChannelMetricWriter messageChannelMetricWriter( public MessageChannelMetricWriter messageChannelMetricWriter(@Qualifier("metricsChannel") MessageChannel channel) {
@Qualifier("metricsChannel") MessageChannel channel) {
return new MessageChannelMetricWriter(channel); return new MessageChannelMetricWriter(channel);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,8 +45,7 @@ public class MetricsDropwizardAutoConfiguration {
private final ReservoirFactory reservoirFactory; private final ReservoirFactory reservoirFactory;
public MetricsDropwizardAutoConfiguration( public MetricsDropwizardAutoConfiguration(ObjectProvider<ReservoirFactory> reservoirFactory) {
ObjectProvider<ReservoirFactory> reservoirFactory) {
this.reservoirFactory = reservoirFactory.getIfAvailable(); this.reservoirFactory = reservoirFactory.getIfAvailable();
} }
@ -57,10 +56,8 @@ public class MetricsDropwizardAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnMissingBean({ DropwizardMetricServices.class, CounterService.class, @ConditionalOnMissingBean({ DropwizardMetricServices.class, CounterService.class, GaugeService.class })
GaugeService.class }) public DropwizardMetricServices dropwizardMetricServices(MetricRegistry metricRegistry) {
public DropwizardMetricServices dropwizardMetricServices(
MetricRegistry metricRegistry) {
if (this.reservoirFactory == null) { if (this.reservoirFactory == null) {
return new DropwizardMetricServices(metricRegistry); return new DropwizardMetricServices(metricRegistry);
} }
@ -70,10 +67,8 @@ public class MetricsDropwizardAutoConfiguration {
} }
@Bean @Bean
public MetricReaderPublicMetrics dropwizardPublicMetrics( public MetricReaderPublicMetrics dropwizardPublicMetrics(MetricRegistry metricRegistry) {
MetricRegistry metricRegistry) { MetricRegistryMetricReader reader = new MetricRegistryMetricReader(metricRegistry);
MetricRegistryMetricReader reader = new MetricRegistryMetricReader(
metricRegistry);
return new MetricReaderPublicMetrics(reader); return new MetricReaderPublicMetrics(reader);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,8 +45,7 @@ import org.springframework.web.servlet.HandlerMapping;
@Order(Ordered.HIGHEST_PRECEDENCE) @Order(Ordered.HIGHEST_PRECEDENCE)
final class MetricsFilter extends OncePerRequestFilter { final class MetricsFilter extends OncePerRequestFilter {
private static final String ATTRIBUTE_STOP_WATCH = MetricsFilter.class.getName() private static final String ATTRIBUTE_STOP_WATCH = MetricsFilter.class.getName() + ".StopWatch";
+ ".StopWatch";
private static final int UNDEFINED_HTTP_STATUS = 999; private static final int UNDEFINED_HTTP_STATUS = 999;
@ -81,8 +80,7 @@ final class MetricsFilter extends OncePerRequestFilter {
KEY_REPLACERS = Collections.unmodifiableSet(replacements); KEY_REPLACERS = Collections.unmodifiableSet(replacements);
} }
MetricsFilter(CounterService counterService, GaugeService gaugeService, MetricsFilter(CounterService counterService, GaugeService gaugeService, MetricFilterProperties properties) {
MetricFilterProperties properties) {
this.counterService = counterService; this.counterService = counterService;
this.gaugeService = gaugeService; this.gaugeService = gaugeService;
this.properties = properties; this.properties = properties;
@ -94,8 +92,7 @@ final class MetricsFilter extends OncePerRequestFilter {
} }
@Override @Override
protected void doFilterInternal(HttpServletRequest request, protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException { throws ServletException, IOException {
StopWatch stopWatch = createStopWatchIfNecessary(request); StopWatch stopWatch = createStopWatchIfNecessary(request);
int status = HttpStatus.INTERNAL_SERVER_ERROR.value(); int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
@ -137,13 +134,11 @@ final class MetricsFilter extends OncePerRequestFilter {
private void recordMetrics(HttpServletRequest request, int status, long time) { private void recordMetrics(HttpServletRequest request, int status, long time) {
String suffix = determineMetricNameSuffix(request); String suffix = determineMetricNameSuffix(request);
submitMetrics(MetricsFilterSubmission.MERGED, request, status, time, suffix); submitMetrics(MetricsFilterSubmission.MERGED, request, status, time, suffix);
submitMetrics(MetricsFilterSubmission.PER_HTTP_METHOD, request, status, time, submitMetrics(MetricsFilterSubmission.PER_HTTP_METHOD, request, status, time, suffix);
suffix);
} }
private String determineMetricNameSuffix(HttpServletRequest request) { private String determineMetricNameSuffix(HttpServletRequest request) {
Object bestMatchingPattern = request Object bestMatchingPattern = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (bestMatchingPattern != null) { if (bestMatchingPattern != null) {
return fixSpecialCharacters(bestMatchingPattern.toString()); return fixSpecialCharacters(bestMatchingPattern.toString());
} }
@ -164,8 +159,8 @@ final class MetricsFilter extends OncePerRequestFilter {
return result; return result;
} }
private void submitMetrics(MetricsFilterSubmission submission, private void submitMetrics(MetricsFilterSubmission submission, HttpServletRequest request, int status, long time,
HttpServletRequest request, int status, long time, String suffix) { String suffix) {
String prefix = ""; String prefix = "";
if (submission == MetricsFilterSubmission.PER_HTTP_METHOD) { if (submission == MetricsFilterSubmission.PER_HTTP_METHOD) {
prefix = request.getMethod() + "."; prefix = request.getMethod() + ".";

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,15 +38,13 @@ abstract class OnEnabledEndpointElementCondition extends SpringBootCondition {
private final Class<? extends Annotation> annotationType; private final Class<? extends Annotation> annotationType;
OnEnabledEndpointElementCondition(String prefix, OnEnabledEndpointElementCondition(String prefix, Class<? extends Annotation> annotationType) {
Class<? extends Annotation> annotationType) {
this.prefix = prefix; this.prefix = prefix;
this.annotationType = annotationType; this.annotationType = annotationType;
} }
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) {
AnnotationAttributes annotationAttributes = AnnotationAttributes AnnotationAttributes annotationAttributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(this.annotationType.getName())); .fromMap(metadata.getAnnotationAttributes(this.annotationType.getName()));
String endpointName = annotationAttributes.getString("value"); String endpointName = annotationAttributes.getString("value");
@ -57,26 +55,23 @@ abstract class OnEnabledEndpointElementCondition extends SpringBootCondition {
return getDefaultEndpointsOutcome(context); return getDefaultEndpointsOutcome(context);
} }
protected ConditionOutcome getEndpointOutcome(ConditionContext context, protected ConditionOutcome getEndpointOutcome(ConditionContext context, String endpointName) {
String endpointName) { RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(),
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( this.prefix + endpointName + ".");
context.getEnvironment(), this.prefix + endpointName + ".");
if (resolver.containsProperty("enabled")) { if (resolver.containsProperty("enabled")) {
boolean match = resolver.getProperty("enabled", Boolean.class, true); boolean match = resolver.getProperty("enabled", Boolean.class, true);
return new ConditionOutcome(match, return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
ConditionMessage.forCondition(this.annotationType).because( .because(this.prefix + endpointName + ".enabled is " + match));
this.prefix + endpointName + ".enabled is " + match));
} }
return null; return null;
} }
protected ConditionOutcome getDefaultEndpointsOutcome(ConditionContext context) { protected ConditionOutcome getDefaultEndpointsOutcome(ConditionContext context) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(),
context.getEnvironment(), this.prefix + "defaults."); this.prefix + "defaults.");
boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true"));
return new ConditionOutcome(match, return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType)
ConditionMessage.forCondition(this.annotationType).because( .because(this.prefix + "defaults.enabled is considered " + match));
this.prefix + "defaults.enabled is considered " + match));
} }
} }

@ -77,8 +77,7 @@ public class PublicMetricsAutoConfiguration {
private final List<MetricReader> metricReaders; private final List<MetricReader> metricReaders;
public PublicMetricsAutoConfiguration( public PublicMetricsAutoConfiguration(@ExportMetricReader ObjectProvider<List<MetricReader>> metricReaders) {
@ExportMetricReader ObjectProvider<List<MetricReader>> metricReaders) {
this.metricReaders = metricReaders.getIfAvailable(); this.metricReaders = metricReaders.getIfAvailable();
} }
@ -90,15 +89,13 @@ public class PublicMetricsAutoConfiguration {
@Bean @Bean
public MetricReaderPublicMetrics metricReaderPublicMetrics() { public MetricReaderPublicMetrics metricReaderPublicMetrics() {
MetricReader[] readers = (this.metricReaders != null) MetricReader[] readers = (this.metricReaders != null)
? this.metricReaders.toArray(new MetricReader[this.metricReaders.size()]) ? this.metricReaders.toArray(new MetricReader[this.metricReaders.size()]) : new MetricReader[0];
: new MetricReader[0];
return new MetricReaderPublicMetrics(new CompositeMetricReader(readers)); return new MetricReaderPublicMetrics(new CompositeMetricReader(readers));
} }
@Bean @Bean
@ConditionalOnBean(RichGaugeReader.class) @ConditionalOnBean(RichGaugeReader.class)
public RichGaugeReaderPublicMetrics richGaugePublicMetrics( public RichGaugeReaderPublicMetrics richGaugePublicMetrics(RichGaugeReader richGaugeReader) {
RichGaugeReader richGaugeReader) {
return new RichGaugeReaderPublicMetrics(richGaugeReader); return new RichGaugeReaderPublicMetrics(richGaugeReader);
} }
@ -137,8 +134,7 @@ public class PublicMetricsAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnBean(CacheStatisticsProvider.class) @ConditionalOnBean(CacheStatisticsProvider.class)
public CachePublicMetrics cachePublicMetrics( public CachePublicMetrics cachePublicMetrics(Map<String, CacheManager> cacheManagers,
Map<String, CacheManager> cacheManagers,
Collection<CacheStatisticsProvider<?>> statisticsProviders) { Collection<CacheStatisticsProvider<?>> statisticsProviders) {
return new CachePublicMetrics(cacheManagers, statisticsProviders); return new CachePublicMetrics(cacheManagers, statisticsProviders);
} }
@ -153,8 +149,7 @@ public class PublicMetricsAutoConfiguration {
@Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME)
@ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class,
name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, search = SearchStrategy.CURRENT)
search = SearchStrategy.CURRENT)
public IntegrationManagementConfigurer managementConfigurer() { public IntegrationManagementConfigurer managementConfigurer() {
IntegrationManagementConfigurer configurer = new IntegrationManagementConfigurer(); IntegrationManagementConfigurer configurer = new IntegrationManagementConfigurer();
configurer.setDefaultCountsEnabled(true); configurer.setDefaultCountsEnabled(true);
@ -166,8 +161,7 @@ public class PublicMetricsAutoConfiguration {
@ConditionalOnMissingBean(name = "springIntegrationPublicMetrics") @ConditionalOnMissingBean(name = "springIntegrationPublicMetrics")
public MetricReaderPublicMetrics springIntegrationPublicMetrics( public MetricReaderPublicMetrics springIntegrationPublicMetrics(
IntegrationManagementConfigurer managementConfigurer) { IntegrationManagementConfigurer managementConfigurer) {
return new MetricReaderPublicMetrics( return new MetricReaderPublicMetrics(new SpringIntegrationMetricReader(managementConfigurer));
new SpringIntegrationMetricReader(managementConfigurer));
} }
} }

@ -40,8 +40,7 @@ import org.springframework.util.StringUtils;
* @author Stephane Nicoll * @author Stephane Nicoll
* @deprecated as of 1.5 since CRaSH is not actively maintained * @deprecated as of 1.5 since CRaSH is not actively maintained
*/ */
@ConfigurationProperties(prefix = ShellProperties.SHELL_PREFIX, @ConfigurationProperties(prefix = ShellProperties.SHELL_PREFIX, ignoreUnknownFields = true)
ignoreUnknownFields = true)
@Deprecated @Deprecated
public class ShellProperties { public class ShellProperties {
@ -63,8 +62,7 @@ public class ShellProperties {
/** /**
* Patterns to use to look for commands. * Patterns to use to look for commands.
*/ */
private String[] commandPathPatterns = new String[] { "classpath*:/commands/**", private String[] commandPathPatterns = new String[] { "classpath*:/commands/**", "classpath*:/crash/commands/**" };
"classpath*:/crash/commands/**" };
/** /**
* Patterns to use to look for configurations. * Patterns to use to look for configurations.
@ -161,8 +159,7 @@ public class ShellProperties {
} }
if (this.commandRefreshInterval > 0) { if (this.commandRefreshInterval > 0) {
properties.put("crash.vfs.refresh_period", properties.put("crash.vfs.refresh_period", String.valueOf(this.commandRefreshInterval));
String.valueOf(this.commandRefreshInterval));
} }
// special handling for disabling Ssh and Telnet support // special handling for disabling Ssh and Telnet support
@ -204,8 +201,7 @@ public class ShellProperties {
/** /**
* Base class for Auth specific properties. * Base class for Auth specific properties.
*/ */
public abstract static class CrshShellAuthenticationProperties public abstract static class CrshShellAuthenticationProperties extends CrshShellProperties {
extends CrshShellProperties {
} }
@ -236,10 +232,8 @@ public class ShellProperties {
protected void validateCrshShellConfig(Properties properties) { protected void validateCrshShellConfig(Properties properties) {
String finalAuth = properties.getProperty("crash.auth"); String finalAuth = properties.getProperty("crash.auth");
if (!this.defaultAuth && !this.type.equals(finalAuth)) { if (!this.defaultAuth && !this.type.equals(finalAuth)) {
logger.warn(String.format( logger.warn(String.format("Shell authentication fell back to method '%s' opposed to "
"Shell authentication fell back to method '%s' opposed to " + "configured method '%s'. Please check your classpath.", finalAuth, this.type));
+ "configured method '%s'. Please check your classpath.",
finalAuth, this.type));
} }
// Make sure we keep track of final authentication method // Make sure we keep track of final authentication method
this.type = finalAuth; this.type = finalAuth;
@ -379,10 +373,8 @@ public class ShellProperties {
/** /**
* Auth specific properties for JAAS authentication. * Auth specific properties for JAAS authentication.
*/ */
@ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.jaas", @ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.jaas", ignoreUnknownFields = false)
ignoreUnknownFields = false) public static class JaasAuthenticationProperties extends CrshShellAuthenticationProperties {
public static class JaasAuthenticationProperties
extends CrshShellAuthenticationProperties {
/** /**
* JAAS domain. * JAAS domain.
@ -409,10 +401,8 @@ public class ShellProperties {
/** /**
* Auth specific properties for key authentication. * Auth specific properties for key authentication.
*/ */
@ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.key", @ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.key", ignoreUnknownFields = false)
ignoreUnknownFields = false) public static class KeyAuthenticationProperties extends CrshShellAuthenticationProperties {
public static class KeyAuthenticationProperties
extends CrshShellAuthenticationProperties {
/** /**
* Path to the authentication key. This should point to a valid ".pem" file. * Path to the authentication key. This should point to a valid ".pem" file.
@ -441,13 +431,10 @@ public class ShellProperties {
/** /**
* Auth specific properties for simple authentication. * Auth specific properties for simple authentication.
*/ */
@ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.simple", @ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.simple", ignoreUnknownFields = false)
ignoreUnknownFields = false) public static class SimpleAuthenticationProperties extends CrshShellAuthenticationProperties {
public static class SimpleAuthenticationProperties
extends CrshShellAuthenticationProperties {
private static final Log logger = LogFactory private static final Log logger = LogFactory.getLog(SimpleAuthenticationProperties.class);
.getLog(SimpleAuthenticationProperties.class);
private User user = new User(); private User user = new User();
@ -457,9 +444,8 @@ public class ShellProperties {
config.put("crash.auth.simple.username", this.user.getName()); config.put("crash.auth.simple.username", this.user.getName());
config.put("crash.auth.simple.password", this.user.getPassword()); config.put("crash.auth.simple.password", this.user.getPassword());
if (this.user.isDefaultPassword()) { if (this.user.isDefaultPassword()) {
logger.info(String.format( logger.info(
"%n%nUsing default password for shell access: %s%n%n", String.format("%n%nUsing default password for shell access: %s%n%n", this.user.getPassword()));
this.user.getPassword()));
} }
} }
@ -503,8 +489,7 @@ public class ShellProperties {
} }
public void setPassword(String password) { public void setPassword(String password) {
if (password.startsWith("${") && password.endsWith("}") if (password.startsWith("${") && password.endsWith("}") || !StringUtils.hasLength(password)) {
|| !StringUtils.hasLength(password)) {
return; return;
} }
this.password = password; this.password = password;
@ -518,10 +503,8 @@ public class ShellProperties {
/** /**
* Auth specific properties for Spring authentication. * Auth specific properties for Spring authentication.
*/ */
@ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.spring", @ConfigurationProperties(prefix = SHELL_PREFIX + ".auth.spring", ignoreUnknownFields = false)
ignoreUnknownFields = false) public static class SpringAuthenticationProperties extends CrshShellAuthenticationProperties {
public static class SpringAuthenticationProperties
extends CrshShellAuthenticationProperties {
/** /**
* Comma-separated list of required roles to login to the CRaSH console. * Comma-separated list of required roles to login to the CRaSH console.
@ -531,8 +514,7 @@ public class ShellProperties {
@Override @Override
protected void applyToCrshShellConfig(Properties config) { protected void applyToCrshShellConfig(Properties config) {
config.put("crash.auth", "spring"); config.put("crash.auth", "spring");
config.put("crash.auth.spring.roles", config.put("crash.auth.spring.roles", StringUtils.arrayToCommaDelimitedString(this.roles));
StringUtils.arrayToCommaDelimitedString(this.roles));
} }
public void setRoles(String[] roles) { public void setRoles(String[] roles) {

@ -44,8 +44,7 @@ import org.springframework.web.servlet.DispatcherServlet;
@Configuration @Configuration
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, ServletRegistration.class }) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, ServletRegistration.class })
@AutoConfigureAfter(TraceRepositoryAutoConfiguration.class) @AutoConfigureAfter(TraceRepositoryAutoConfiguration.class)
@ConditionalOnProperty(prefix = "endpoints.trace.filter", name = "enabled", @ConditionalOnProperty(prefix = "endpoints.trace.filter", name = "enabled", matchIfMissing = true)
matchIfMissing = true)
@EnableConfigurationProperties(TraceProperties.class) @EnableConfigurationProperties(TraceProperties.class)
public class TraceWebFilterAutoConfiguration { public class TraceWebFilterAutoConfiguration {
@ -55,8 +54,7 @@ public class TraceWebFilterAutoConfiguration {
private final ErrorAttributes errorAttributes; private final ErrorAttributes errorAttributes;
public TraceWebFilterAutoConfiguration(TraceRepository traceRepository, public TraceWebFilterAutoConfiguration(TraceRepository traceRepository, TraceProperties traceProperties,
TraceProperties traceProperties,
ObjectProvider<ErrorAttributes> errorAttributes) { ObjectProvider<ErrorAttributes> errorAttributes) {
this.traceRepository = traceRepository; this.traceRepository = traceRepository;
this.traceProperties = traceProperties; this.traceProperties = traceProperties;
@ -66,8 +64,7 @@ public class TraceWebFilterAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public WebRequestTraceFilter webRequestLoggingFilter(BeanFactory beanFactory) { public WebRequestTraceFilter webRequestLoggingFilter(BeanFactory beanFactory) {
WebRequestTraceFilter filter = new WebRequestTraceFilter(this.traceRepository, WebRequestTraceFilter filter = new WebRequestTraceFilter(this.traceRepository, this.traceProperties);
this.traceProperties);
if (this.errorAttributes != null) { if (this.errorAttributes != null) {
filter.setErrorAttributes(this.errorAttributes); filter.setErrorAttributes(this.errorAttributes);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,11 +42,9 @@ import org.springframework.cache.CacheManager;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache> public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache> implements CacheStatisticsProvider<C> {
implements CacheStatisticsProvider<C> {
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory.getLogger(AbstractJmxCacheStatisticsProvider.class);
.getLogger(AbstractJmxCacheStatisticsProvider.class);
private MBeanServer mBeanServer; private MBeanServer mBeanServer;
@ -71,8 +69,7 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
* @throws MalformedObjectNameException if the {@link ObjectName} for that cache is * @throws MalformedObjectNameException if the {@link ObjectName} for that cache is
* invalid * invalid
*/ */
protected abstract ObjectName getObjectName(C cache) protected abstract ObjectName getObjectName(C cache) throws MalformedObjectNameException;
throws MalformedObjectNameException;
/** /**
* Return the current {@link CacheStatistics} snapshot from the MBean identified by * Return the current {@link CacheStatistics} snapshot from the MBean identified by
@ -82,8 +79,7 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
*/ */
protected abstract CacheStatistics getCacheStatistics(ObjectName objectName); protected abstract CacheStatistics getCacheStatistics(ObjectName objectName);
private ObjectName internalGetObjectName(C cache) private ObjectName internalGetObjectName(C cache) throws MalformedObjectNameException {
throws MalformedObjectNameException {
String cacheName = cache.getName(); String cacheName = cache.getName();
ObjectNameWrapper value = this.caches.get(cacheName); ObjectNameWrapper value = this.caches.get(cacheName);
if (value != null) { if (value != null) {
@ -101,8 +97,7 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
return this.mBeanServer; return this.mBeanServer;
} }
protected <T> T getAttribute(ObjectName objectName, String attributeName, protected <T> T getAttribute(ObjectName objectName, String attributeName, Class<T> type) {
Class<T> type) {
try { try {
Object attribute = getMBeanServer().getAttribute(objectName, attributeName); Object attribute = getMBeanServer().getAttribute(objectName, attributeName);
return type.cast(attribute); return type.cast(attribute);
@ -111,8 +106,8 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
catch (AttributeNotFoundException ex) { catch (AttributeNotFoundException ex) {
throw new IllegalStateException("Unexpected: MBean with name '" + objectName throw new IllegalStateException("Unexpected: MBean with name '" + objectName + "' "
+ "' " + "does not expose attribute with name " + attributeName, ex); + "does not expose attribute with name " + attributeName, ex);
} }
catch (ReflectionException ex) { catch (ReflectionException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,12 +27,10 @@ import org.springframework.cache.caffeine.CaffeineCache;
* @author Eddú Meléndez * @author Eddú Meléndez
* @since 1.4.0 * @since 1.4.0
*/ */
public class CaffeineCacheStatisticsProvider public class CaffeineCacheStatisticsProvider implements CacheStatisticsProvider<CaffeineCache> {
implements CacheStatisticsProvider<CaffeineCache> {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, CaffeineCache cache) {
CaffeineCache cache) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
statistics.setSize(cache.getNativeCache().estimatedSize()); statistics.setSize(cache.getNativeCache().estimatedSize());
CacheStats caffeineStatistics = cache.getNativeCache().stats(); CacheStats caffeineStatistics = cache.getNativeCache().stats();

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,12 +25,10 @@ import org.springframework.cache.concurrent.ConcurrentMapCache;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class ConcurrentMapCacheStatisticsProvider public class ConcurrentMapCacheStatisticsProvider implements CacheStatisticsProvider<ConcurrentMapCache> {
implements CacheStatisticsProvider<ConcurrentMapCache> {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, ConcurrentMapCache cache) {
ConcurrentMapCache cache) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
statistics.setSize((long) cache.getNativeCache().size()); statistics.setSize((long) cache.getNativeCache().size());
return statistics; return statistics;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -80,8 +80,7 @@ public class DefaultCacheStatistics implements CacheStatistics {
this.missRatio = missRatio; this.missRatio = missRatio;
} }
private <T extends Number> void addMetric(Collection<Metric<?>> metrics, String name, private <T extends Number> void addMetric(Collection<Metric<?>> metrics, String name, T value) {
T value) {
if (value != null) { if (value != null) {
metrics.add(new Metric<T>(name, value)); metrics.add(new Metric<T>(name, value));
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,8 +30,7 @@ import org.springframework.cache.ehcache.EhCacheCache;
public class EhCacheStatisticsProvider implements CacheStatisticsProvider<EhCacheCache> { public class EhCacheStatisticsProvider implements CacheStatisticsProvider<EhCacheCache> {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, EhCacheCache cache) {
EhCacheCache cache) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
StatisticsGateway ehCacheStatistics = cache.getNativeCache().getStatistics(); StatisticsGateway ehCacheStatistics = cache.getNativeCache().getStatistics();
statistics.setSize(ehCacheStatistics.getSize()); statistics.setSize(ehCacheStatistics.getSize());

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,8 +32,7 @@ import org.springframework.cache.guava.GuavaCache;
public class GuavaCacheStatisticsProvider implements CacheStatisticsProvider<GuavaCache> { public class GuavaCacheStatisticsProvider implements CacheStatisticsProvider<GuavaCache> {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, GuavaCache cache) {
GuavaCache cache) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
statistics.setSize(cache.getNativeCache().size()); statistics.setSize(cache.getNativeCache().size());
CacheStats guavaStats = cache.getNativeCache().stats(); CacheStats guavaStats = cache.getNativeCache().stats();

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -28,15 +28,12 @@ import org.springframework.cache.CacheManager;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class HazelcastCacheStatisticsProvider public class HazelcastCacheStatisticsProvider implements CacheStatisticsProvider<HazelcastCache> {
implements CacheStatisticsProvider<HazelcastCache> {
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, public CacheStatistics getCacheStatistics(CacheManager cacheManager, HazelcastCache cache) {
HazelcastCache cache) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
LocalMapStats mapStatistics = ((IMap<?, ?>) cache.getNativeCache()) LocalMapStats mapStatistics = ((IMap<?, ?>) cache.getNativeCache()).getLocalMapStats();
.getLocalMapStats();
statistics.setSize(mapStatistics.getOwnedEntryCount()); statistics.setSize(mapStatistics.getOwnedEntryCount());
statistics.setGetCacheCounts(mapStatistics.getHits(), statistics.setGetCacheCounts(mapStatistics.getHits(),
mapStatistics.getGetOperationCount() - mapStatistics.getHits()); mapStatistics.getGetOperationCount() - mapStatistics.getHits());

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,15 +30,12 @@ import org.infinispan.spring.provider.SpringCache;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class InfinispanCacheStatisticsProvider public class InfinispanCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<SpringCache> {
extends AbstractJmxCacheStatisticsProvider<SpringCache> {
@Override @Override
protected ObjectName getObjectName(SpringCache cache) protected ObjectName getObjectName(SpringCache cache) throws MalformedObjectNameException {
throws MalformedObjectNameException {
ObjectName name = new ObjectName( ObjectName name = new ObjectName(
"org.infinispan:component=Statistics,type=Cache,name=\"" + cache.getName() "org.infinispan:component=Statistics,type=Cache,name=\"" + cache.getName() + "(local)\",*");
+ "(local)\",*");
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null); Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
if (instances.size() == 1) { if (instances.size() == 1) {
return instances.iterator().next().getObjectName(); return instances.iterator().next().getObjectName();
@ -61,8 +58,7 @@ public class InfinispanCacheStatisticsProvider
return statistics; return statistics;
} }
private void initializeStats(ObjectName objectName, private void initializeStats(ObjectName objectName, DefaultCacheStatistics statistics) {
DefaultCacheStatistics statistics) {
Double hitRatio = getAttribute(objectName, "hitRatio", Double.class); Double hitRatio = getAttribute(objectName, "hitRatio", Double.class);
if ((hitRatio != null)) { if ((hitRatio != null)) {
statistics.setHitRatio(hitRatio); statistics.setHitRatio(hitRatio);

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,14 +30,11 @@ import org.springframework.cache.jcache.JCacheCache;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class JCacheCacheStatisticsProvider public class JCacheCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<JCacheCache> {
extends AbstractJmxCacheStatisticsProvider<JCacheCache> {
@Override @Override
protected ObjectName getObjectName(JCacheCache cache) protected ObjectName getObjectName(JCacheCache cache) throws MalformedObjectNameException {
throws MalformedObjectNameException { ObjectName name = new ObjectName("javax.cache:type=CacheStatistics,Cache=" + cache.getName() + ",*");
ObjectName name = new ObjectName(
"javax.cache:type=CacheStatistics,Cache=" + cache.getName() + ",*");
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null); Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
if (instances.size() == 1) { if (instances.size() == 1) {
return instances.iterator().next().getObjectName(); return instances.iterator().next().getObjectName();
@ -50,10 +47,8 @@ public class JCacheCacheStatisticsProvider
protected CacheStatistics getCacheStatistics(ObjectName objectName) { protected CacheStatistics getCacheStatistics(ObjectName objectName) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
Float hitPercentage = getAttribute(objectName, "CacheHitPercentage", Float.class); Float hitPercentage = getAttribute(objectName, "CacheHitPercentage", Float.class);
Float missPercentage = getAttribute(objectName, "CacheMissPercentage", Float missPercentage = getAttribute(objectName, "CacheMissPercentage", Float.class);
Float.class); if ((hitPercentage != null && missPercentage != null) && (hitPercentage > 0 || missPercentage > 0)) {
if ((hitPercentage != null && missPercentage != null)
&& (hitPercentage > 0 || missPercentage > 0)) {
statistics.setHitRatio(hitPercentage / (double) 100); statistics.setHitRatio(hitPercentage / (double) 100);
statistics.setMissRatio(missPercentage / (double) 100); statistics.setMissRatio(missPercentage / (double) 100);
} }

@ -50,57 +50,50 @@ import org.springframework.web.servlet.HandlerInterceptor;
* @since 1.5.0 * @since 1.5.0
*/ */
@Configuration @Configuration
@ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled", @ConditionalOnProperty(prefix = "management.cloudfoundry", name = "enabled", matchIfMissing = true)
matchIfMissing = true)
@ConditionalOnBean(MvcEndpoints.class) @ConditionalOnBean(MvcEndpoints.class)
@AutoConfigureAfter(EndpointWebMvcAutoConfiguration.class) @AutoConfigureAfter(EndpointWebMvcAutoConfiguration.class)
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) @ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
public class CloudFoundryActuatorAutoConfiguration { public class CloudFoundryActuatorAutoConfiguration {
@Bean @Bean
public CloudFoundryEndpointHandlerMapping cloudFoundryEndpointHandlerMapping( public CloudFoundryEndpointHandlerMapping cloudFoundryEndpointHandlerMapping(MvcEndpoints mvcEndpoints,
MvcEndpoints mvcEndpoints, RestTemplateBuilder restTemplateBuilder, RestTemplateBuilder restTemplateBuilder, Environment environment) {
Environment environment) {
Set<NamedMvcEndpoint> endpoints = new LinkedHashSet<NamedMvcEndpoint>( Set<NamedMvcEndpoint> endpoints = new LinkedHashSet<NamedMvcEndpoint>(
mvcEndpoints.getEndpoints(NamedMvcEndpoint.class)); mvcEndpoints.getEndpoints(NamedMvcEndpoint.class));
HandlerInterceptor securityInterceptor = getSecurityInterceptor( HandlerInterceptor securityInterceptor = getSecurityInterceptor(restTemplateBuilder, environment);
restTemplateBuilder, environment);
CorsConfiguration corsConfiguration = getCorsConfiguration(); CorsConfiguration corsConfiguration = getCorsConfiguration();
CloudFoundryEndpointHandlerMapping mapping = new CloudFoundryEndpointHandlerMapping( CloudFoundryEndpointHandlerMapping mapping = new CloudFoundryEndpointHandlerMapping(endpoints,
endpoints, corsConfiguration, securityInterceptor); corsConfiguration, securityInterceptor);
mapping.setPrefix("/cloudfoundryapplication"); mapping.setPrefix("/cloudfoundryapplication");
return mapping; return mapping;
} }
private HandlerInterceptor getSecurityInterceptor( private HandlerInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder,
RestTemplateBuilder restTemplateBuilder, Environment environment) { Environment environment) {
CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService( CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(restTemplateBuilder,
restTemplateBuilder, environment); environment);
TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService); TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService);
HandlerInterceptor securityInterceptor = new CloudFoundrySecurityInterceptor( HandlerInterceptor securityInterceptor = new CloudFoundrySecurityInterceptor(tokenValidator,
tokenValidator, cloudfoundrySecurityService, cloudfoundrySecurityService, environment.getProperty("vcap.application.application_id"));
environment.getProperty("vcap.application.application_id"));
return securityInterceptor; return securityInterceptor;
} }
private CloudFoundrySecurityService getCloudFoundrySecurityService( private CloudFoundrySecurityService getCloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder,
RestTemplateBuilder restTemplateBuilder, Environment environment) { Environment environment) {
RelaxedPropertyResolver cloudFoundryProperties = new RelaxedPropertyResolver( RelaxedPropertyResolver cloudFoundryProperties = new RelaxedPropertyResolver(environment,
environment, "management.cloudfoundry."); "management.cloudfoundry.");
String cloudControllerUrl = environment.getProperty("vcap.application.cf_api"); String cloudControllerUrl = environment.getProperty("vcap.application.cf_api");
boolean skipSslValidation = cloudFoundryProperties boolean skipSslValidation = cloudFoundryProperties.getProperty("skip-ssl-validation", Boolean.class, false);
.getProperty("skip-ssl-validation", Boolean.class, false); return (cloudControllerUrl != null)
return (cloudControllerUrl != null) ? new CloudFoundrySecurityService( ? new CloudFoundrySecurityService(restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null;
restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null;
} }
private CorsConfiguration getCorsConfiguration() { private CorsConfiguration getCorsConfiguration() {
CorsConfiguration corsConfiguration = new CorsConfiguration(); CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL); corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
corsConfiguration.setAllowedMethods( corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name())); corsConfiguration.setAllowedHeaders(Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
corsConfiguration.setAllowedHeaders(
Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type"));
return corsConfiguration; return corsConfiguration;
} }
@ -116,13 +109,11 @@ public class CloudFoundryActuatorAutoConfiguration {
return new CloudFoundryIgnoredRequestCustomizer(); return new CloudFoundryIgnoredRequestCustomizer();
} }
private static class CloudFoundryIgnoredRequestCustomizer private static class CloudFoundryIgnoredRequestCustomizer implements IgnoredRequestCustomizer {
implements IgnoredRequestCustomizer {
@Override @Override
public void customize(WebSecurity.IgnoredRequestConfigurer configurer) { public void customize(WebSecurity.IgnoredRequestConfigurer configurer) {
configurer.requestMatchers( configurer.requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
new AntPathRequestMatcher("/cloudfoundryapplication/**"));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -57,8 +57,7 @@ class CloudFoundryDiscoveryMvcEndpoint extends AbstractMvcEndpoint {
AccessLevel accessLevel = AccessLevel.get(request); AccessLevel accessLevel = AccessLevel.get(request);
for (NamedMvcEndpoint endpoint : this.endpoints) { for (NamedMvcEndpoint endpoint : this.endpoints) {
if (accessLevel != null && accessLevel.isAccessAllowed(endpoint.getPath())) { if (accessLevel != null && accessLevel.isAccessAllowed(endpoint.getPath())) {
links.put(endpoint.getName(), links.put(endpoint.getName(), Link.withHref(url + "/" + endpoint.getName()));
Link.withHref(url + "/" + endpoint.getName()));
} }
} }
return Collections.singletonMap("_links", links); return Collections.singletonMap("_links", links);

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,11 +34,10 @@ import org.springframework.web.servlet.HandlerMapping;
* *
* @author Madhura Bhave * @author Madhura Bhave
*/ */
class CloudFoundryEndpointHandlerMapping class CloudFoundryEndpointHandlerMapping extends AbstractEndpointHandlerMapping<NamedMvcEndpoint> {
extends AbstractEndpointHandlerMapping<NamedMvcEndpoint> {
CloudFoundryEndpointHandlerMapping(Set<? extends NamedMvcEndpoint> endpoints, CloudFoundryEndpointHandlerMapping(Set<? extends NamedMvcEndpoint> endpoints, CorsConfiguration corsConfiguration,
CorsConfiguration corsConfiguration, HandlerInterceptor securityInterceptor) { HandlerInterceptor securityInterceptor) {
super(endpoints, corsConfiguration); super(endpoints, corsConfiguration);
setSecurityInterceptor(securityInterceptor); setSecurityInterceptor(securityInterceptor);
} }
@ -59,8 +58,7 @@ class CloudFoundryEndpointHandlerMapping
} }
} }
if (healthMvcEndpoint != null) { if (healthMvcEndpoint != null) {
endpoints.add( endpoints.add(new CloudFoundryHealthMvcEndpoint(healthMvcEndpoint.getDelegate()));
new CloudFoundryHealthMvcEndpoint(healthMvcEndpoint.getDelegate()));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,8 +38,7 @@ class CloudFoundryHealthMvcEndpoint extends HealthMvcEndpoint {
} }
@Override @Override
protected boolean exposeHealthDetails(HttpServletRequest request, protected boolean exposeHealthDetails(HttpServletRequest request, Principal principal) {
Principal principal) {
return true; return true;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,8 +41,7 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
*/ */
class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter { class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
private static final Log logger = LogFactory private static final Log logger = LogFactory.getLog(CloudFoundrySecurityInterceptor.class);
.getLog(CloudFoundrySecurityInterceptor.class);
private final TokenValidator tokenValidator; private final TokenValidator tokenValidator;
@ -51,16 +50,15 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
private final String applicationId; private final String applicationId;
CloudFoundrySecurityInterceptor(TokenValidator tokenValidator, CloudFoundrySecurityInterceptor(TokenValidator tokenValidator,
CloudFoundrySecurityService cloudFoundrySecurityService, CloudFoundrySecurityService cloudFoundrySecurityService, String applicationId) {
String applicationId) {
this.tokenValidator = tokenValidator; this.tokenValidator = tokenValidator;
this.cloudFoundrySecurityService = cloudFoundrySecurityService; this.cloudFoundrySecurityService = cloudFoundrySecurityService;
this.applicationId = applicationId; this.applicationId = applicationId;
} }
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
Object handler) throws Exception { throws Exception {
if (CorsUtils.isPreFlightRequest(request)) { if (CorsUtils.isPreFlightRequest(request)) {
return true; return true;
} }
@ -74,8 +72,7 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
"Cloud controller URL is not available"); "Cloud controller URL is not available");
} }
HandlerMethod handlerMethod = (HandlerMethod) handler; HandlerMethod handlerMethod = (HandlerMethod) handler;
if (HttpMethod.OPTIONS.matches(request.getMethod()) if (HttpMethod.OPTIONS.matches(request.getMethod()) && !(handlerMethod.getBean() instanceof MvcEndpoint)) {
&& !(handlerMethod.getBean() instanceof MvcEndpoint)) {
return true; return true;
} }
MvcEndpoint mvcEndpoint = (MvcEndpoint) handlerMethod.getBean(); MvcEndpoint mvcEndpoint = (MvcEndpoint) handlerMethod.getBean();
@ -84,23 +81,19 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
catch (CloudFoundryAuthorizationException ex) { catch (CloudFoundryAuthorizationException ex) {
logger.error(ex); logger.error(ex);
response.setContentType(MediaType.APPLICATION_JSON.toString()); response.setContentType(MediaType.APPLICATION_JSON.toString());
response.getWriter() response.getWriter().write("{\"security_error\":\"" + ex.getMessage() + "\"}");
.write("{\"security_error\":\"" + ex.getMessage() + "\"}");
response.setStatus(ex.getStatusCode().value()); response.setStatus(ex.getStatusCode().value());
return false; return false;
} }
return true; return true;
} }
private void check(HttpServletRequest request, MvcEndpoint mvcEndpoint) private void check(HttpServletRequest request, MvcEndpoint mvcEndpoint) throws Exception {
throws Exception {
Token token = getToken(request); Token token = getToken(request);
this.tokenValidator.validate(token); this.tokenValidator.validate(token);
AccessLevel accessLevel = this.cloudFoundrySecurityService AccessLevel accessLevel = this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId);
.getAccessLevel(token.toString(), this.applicationId);
if (!accessLevel.isAccessAllowed(mvcEndpoint.getPath())) { if (!accessLevel.isAccessAllowed(mvcEndpoint.getPath())) {
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied");
"Access denied");
} }
accessLevel.put(request); accessLevel.put(request);
} }
@ -108,8 +101,7 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
private Token getToken(HttpServletRequest request) { private Token getToken(HttpServletRequest request) {
String authorization = request.getHeader("Authorization"); String authorization = request.getHeader("Authorization");
String bearerPrefix = "bearer "; String bearerPrefix = "bearer ";
if (authorization == null if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
|| !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) {
throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION, throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION,
"Authorization header is missing or invalid"); "Authorization header is missing or invalid");
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,13 +45,12 @@ class CloudFoundrySecurityService {
private String uaaUrl; private String uaaUrl;
CloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, CloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, String cloudControllerUrl,
String cloudControllerUrl, boolean skipSslValidation) { boolean skipSslValidation) {
Assert.notNull(restTemplateBuilder, "RestTemplateBuilder must not be null"); Assert.notNull(restTemplateBuilder, "RestTemplateBuilder must not be null");
Assert.notNull(cloudControllerUrl, "CloudControllerUrl must not be null"); Assert.notNull(cloudControllerUrl, "CloudControllerUrl must not be null");
if (skipSslValidation) { if (skipSslValidation) {
restTemplateBuilder = restTemplateBuilder restTemplateBuilder = restTemplateBuilder.requestFactory(SkipSslVerificationHttpRequestFactory.class);
.requestFactory(SkipSslVerificationHttpRequestFactory.class);
} }
this.restTemplate = restTemplateBuilder.build(); this.restTemplate = restTemplateBuilder.build();
this.cloudControllerUrl = cloudControllerUrl; this.cloudControllerUrl = cloudControllerUrl;
@ -64,12 +63,10 @@ class CloudFoundrySecurityService {
* @return the access level that should be granted * @return the access level that should be granted
* @throws CloudFoundryAuthorizationException if the token is not authorized * @throws CloudFoundryAuthorizationException if the token is not authorized
*/ */
public AccessLevel getAccessLevel(String token, String applicationId) public AccessLevel getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException {
throws CloudFoundryAuthorizationException {
try { try {
URI uri = getPermissionsUri(applicationId); URI uri = getPermissionsUri(applicationId);
RequestEntity<?> request = RequestEntity.get(uri) RequestEntity<?> request = RequestEntity.get(uri).header("Authorization", "bearer " + token).build();
.header("Authorization", "bearer " + token).build();
Map<?, ?> body = this.restTemplate.exchange(request, Map.class).getBody(); Map<?, ?> body = this.restTemplate.exchange(request, Map.class).getBody();
if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) { if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) {
return AccessLevel.FULL; return AccessLevel.FULL;
@ -78,22 +75,18 @@ class CloudFoundrySecurityService {
} }
catch (HttpClientErrorException ex) { catch (HttpClientErrorException ex) {
if (ex.getStatusCode().equals(HttpStatus.FORBIDDEN)) { if (ex.getStatusCode().equals(HttpStatus.FORBIDDEN)) {
throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied");
"Access denied");
} }
throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", ex);
"Invalid token", ex);
} }
catch (HttpServerErrorException ex) { catch (HttpServerErrorException ex) {
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable");
"Cloud controller not reachable");
} }
} }
private URI getPermissionsUri(String applicationId) { private URI getPermissionsUri(String applicationId) {
try { try {
return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions");
+ "/permissions");
} }
catch (URISyntaxException ex) { catch (URISyntaxException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
@ -106,12 +99,10 @@ class CloudFoundrySecurityService {
*/ */
public Map<String, String> fetchTokenKeys() { public Map<String, String> fetchTokenKeys() {
try { try {
return extractTokenKeys(this.restTemplate return extractTokenKeys(this.restTemplate.getForObject(getUaaUrl() + "/token_keys", Map.class));
.getForObject(getUaaUrl() + "/token_keys", Map.class));
} }
catch (HttpStatusCodeException ex) { catch (HttpStatusCodeException ex) {
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "UAA not reachable");
"UAA not reachable");
} }
} }
@ -131,8 +122,7 @@ class CloudFoundrySecurityService {
public String getUaaUrl() { public String getUaaUrl() {
if (this.uaaUrl == null) { if (this.uaaUrl == null) {
try { try {
Map<?, ?> response = this.restTemplate Map<?, ?> response = this.restTemplate.getForObject(this.cloudControllerUrl + "/info", Map.class);
.getForObject(this.cloudControllerUrl + "/info", Map.class);
this.uaaUrl = (String) response.get("token_endpoint"); this.uaaUrl = (String) response.get("token_endpoint");
} }
catch (HttpStatusCodeException ex) { catch (HttpStatusCodeException ex) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,8 +39,7 @@ import org.springframework.http.client.SimpleClientHttpRequestFactory;
class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFactory { class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFactory {
@Override @Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
throws IOException {
if (connection instanceof HttpsURLConnection) { if (connection instanceof HttpsURLConnection) {
prepareHttpsConnection((HttpsURLConnection) connection); prepareHttpsConnection((HttpsURLConnection) connection);
} }
@ -59,8 +58,7 @@ class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFacto
private SSLSocketFactory createSslSocketFactory() throws Exception { private SSLSocketFactory createSslSocketFactory() throws Exception {
SSLContext context = SSLContext.getInstance("TLS"); SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new SkipX509TrustManager() }, context.init(null, new TrustManager[] { new SkipX509TrustManager() }, new SecureRandom());
new SecureRandom());
return context.getSocketFactory(); return context.getSocketFactory();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -46,16 +46,14 @@ class Token {
int firstPeriod = encoded.indexOf('.'); int firstPeriod = encoded.indexOf('.');
int lastPeriod = encoded.lastIndexOf('.'); int lastPeriod = encoded.lastIndexOf('.');
if (firstPeriod <= 0 || lastPeriod <= firstPeriod) { if (firstPeriod <= 0 || lastPeriod <= firstPeriod) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
"JWT must have header, body and signature"); "JWT must have header, body and signature");
} }
this.header = parseJson(encoded.substring(0, firstPeriod)); this.header = parseJson(encoded.substring(0, firstPeriod));
this.claims = parseJson(encoded.substring(firstPeriod + 1, lastPeriod)); this.claims = parseJson(encoded.substring(firstPeriod + 1, lastPeriod));
this.signature = encoded.substring(lastPeriod + 1); this.signature = encoded.substring(lastPeriod + 1);
if (!StringUtils.hasLength(this.signature)) { if (!StringUtils.hasLength(this.signature)) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
"Token must have non-empty crypto segment"); "Token must have non-empty crypto segment");
} }
} }
@ -66,8 +64,7 @@ class Token {
return JsonParserFactory.getJsonParser().parseMap(new String(bytes, UTF_8)); return JsonParserFactory.getJsonParser().parseMap(new String(bytes, UTF_8));
} }
catch (RuntimeException ex) { catch (RuntimeException ex) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
"Token could not be parsed", ex); "Token could not be parsed", ex);
} }
} }
@ -105,13 +102,11 @@ class Token {
private <T> T getRequired(Map<String, Object> map, String key, Class<T> type) { private <T> T getRequired(Map<String, Object> map, String key, Class<T> type) {
Object value = map.get(key); Object value = map.get(key);
if (value == null) { if (value == null) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
"Unable to get value from key " + key); "Unable to get value from key " + key);
} }
if (!type.isInstance(value)) { if (!type.isInstance(value)) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN,
"Unexpected value type from key " + key + " value " + value); "Unexpected value type from key " + key + " value " + value);
} }
return (T) value; return (T) value;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,12 +55,10 @@ class TokenValidator {
private void validateAlgorithm(Token token) { private void validateAlgorithm(Token token) {
String algorithm = token.getSignatureAlgorithm(); String algorithm = token.getSignatureAlgorithm();
if (algorithm == null) { if (algorithm == null) {
throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, "Signing algorithm cannot be null");
"Signing algorithm cannot be null");
} }
if (!algorithm.equals("RS256")) { if (!algorithm.equals("RS256")) {
throw new CloudFoundryAuthorizationException( throw new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM,
"Signing algorithm " + algorithm + " not supported"); "Signing algorithm " + algorithm + " not supported");
} }
} }
@ -103,8 +101,7 @@ class TokenValidator {
} }
} }
private PublicKey getPublicKey(String key) private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
throws NoSuchAlgorithmException, InvalidKeySpecException {
key = key.replace("-----BEGIN PUBLIC KEY-----\n", ""); key = key.replace("-----BEGIN PUBLIC KEY-----\n", "");
key = key.replace("-----END PUBLIC KEY-----", ""); key = key.replace("-----END PUBLIC KEY-----", "");
key = key.trim().replace("\n", ""); key = key.trim().replace("\n", "");
@ -116,8 +113,7 @@ class TokenValidator {
private void validateExpiry(Token token) { private void validateExpiry(Token token) {
long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
if (currentTime > token.getExpiry()) { if (currentTime > token.getExpiry()) {
throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired");
"Token expired");
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,30 +33,26 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
class OnEnabledEndpointCondition extends SpringBootCondition { class OnEnabledEndpointCondition extends SpringBootCondition {
@Override @Override
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
AnnotatedTypeMetadata metadata) { AnnotationAttributes annotationAttributes = AnnotationAttributes
AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(metadata .fromMap(metadata.getAnnotationAttributes(ConditionalOnEnabledEndpoint.class.getName()));
.getAnnotationAttributes(ConditionalOnEnabledEndpoint.class.getName()));
String endpointName = annotationAttributes.getString("value"); String endpointName = annotationAttributes.getString("value");
boolean enabledByDefault = annotationAttributes.getBoolean("enabledByDefault"); boolean enabledByDefault = annotationAttributes.getBoolean("enabledByDefault");
ConditionOutcome outcome = determineEndpointOutcome(endpointName, ConditionOutcome outcome = determineEndpointOutcome(endpointName, enabledByDefault, context);
enabledByDefault, context);
if (outcome != null) { if (outcome != null) {
return outcome; return outcome;
} }
return determineAllEndpointsOutcome(context); return determineAllEndpointsOutcome(context);
} }
private ConditionOutcome determineEndpointOutcome(String endpointName, private ConditionOutcome determineEndpointOutcome(String endpointName, boolean enabledByDefault,
boolean enabledByDefault, ConditionContext context) { ConditionContext context) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(),
context.getEnvironment(), "endpoints." + endpointName + "."); "endpoints." + endpointName + ".");
if (resolver.containsProperty("enabled") || !enabledByDefault) { if (resolver.containsProperty("enabled") || !enabledByDefault) {
boolean match = resolver.getProperty("enabled", Boolean.class, boolean match = resolver.getProperty("enabled", Boolean.class, enabledByDefault);
enabledByDefault);
ConditionMessage message = ConditionMessage ConditionMessage message = ConditionMessage
.forCondition(ConditionalOnEnabledEndpoint.class, .forCondition(ConditionalOnEnabledEndpoint.class, "(" + endpointName + ")")
"(" + endpointName + ")")
.because(match ? "enabled" : "disabled"); .because(match ? "enabled" : "disabled");
return new ConditionOutcome(match, message); return new ConditionOutcome(match, message);
} }
@ -64,13 +60,10 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
} }
private ConditionOutcome determineAllEndpointsOutcome(ConditionContext context) { private ConditionOutcome determineAllEndpointsOutcome(ConditionContext context) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), "endpoints.");
context.getEnvironment(), "endpoints.");
boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true"));
ConditionMessage message = ConditionMessage ConditionMessage message = ConditionMessage.forCondition(ConditionalOnEnabledEndpoint.class)
.forCondition(ConditionalOnEnabledEndpoint.class) .because("All endpoints are " + (match ? "enabled" : "disabled") + " by default");
.because("All endpoints are " + (match ? "enabled" : "disabled")
+ " by default");
return new ConditionOutcome(match, message); return new ConditionOutcome(match, message);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -101,8 +101,7 @@ public abstract class AbstractEndpoint<T> implements Endpoint<T>, EnvironmentAwa
public void setId(String id) { public void setId(String id) {
Assert.notNull(id, "Id must not be null"); Assert.notNull(id, "Id must not be null");
Assert.isTrue(ID_PATTERN.matcher(id).matches(), Assert.isTrue(ID_PATTERN.matcher(id).matches(), "Id must only contains letters, numbers and '_'");
"Id must only contains letters, numbers and '_'");
this.id = id; this.id = id;
} }
@ -117,8 +116,7 @@ public abstract class AbstractEndpoint<T> implements Endpoint<T>, EnvironmentAwa
@Override @Override
public boolean isSensitive() { public boolean isSensitive() {
return EndpointProperties.isSensitive(this.environment, this.sensitive, return EndpointProperties.isSensitive(this.environment, this.sensitive, this.sensitiveDefault);
this.sensitiveDefault);
} }
public void setSensitive(Boolean sensitive) { public void setSensitive(Boolean sensitive) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -80,8 +80,7 @@ public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
this.positiveMatches = new LinkedMultiValueMap<String, MessageAndCondition>(); this.positiveMatches = new LinkedMultiValueMap<String, MessageAndCondition>();
this.negativeMatches = new LinkedHashMap<String, MessageAndConditions>(); this.negativeMatches = new LinkedHashMap<String, MessageAndConditions>();
this.exclusions = report.getExclusions(); this.exclusions = report.getExclusions();
for (Map.Entry<String, ConditionAndOutcomes> entry : report for (Map.Entry<String, ConditionAndOutcomes> entry : report.getConditionAndOutcomesBySource().entrySet()) {
.getConditionAndOutcomesBySource().entrySet()) {
if (entry.getValue().isFullMatch()) { if (entry.getValue().isFullMatch()) {
add(this.positiveMatches, entry.getKey(), entry.getValue()); add(this.positiveMatches, entry.getKey(), entry.getValue());
} }
@ -137,8 +136,8 @@ public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
public MessageAndConditions(ConditionAndOutcomes conditionAndOutcomes) { public MessageAndConditions(ConditionAndOutcomes conditionAndOutcomes) {
for (ConditionAndOutcome conditionAndOutcome : conditionAndOutcomes) { for (ConditionAndOutcome conditionAndOutcome : conditionAndOutcomes) {
List<MessageAndCondition> target = (conditionAndOutcome.getOutcome() List<MessageAndCondition> target = (conditionAndOutcome.getOutcome().isMatch() ? this.matched
.isMatch() ? this.matched : this.notMatched); : this.notMatched);
target.add(new MessageAndCondition(conditionAndOutcome)); target.add(new MessageAndCondition(conditionAndOutcome));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,8 +41,7 @@ import org.springframework.util.Assert;
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@ConfigurationProperties(prefix = "endpoints.beans") @ConfigurationProperties(prefix = "endpoints.beans")
public class BeansEndpoint extends AbstractEndpoint<List<Object>> public class BeansEndpoint extends AbstractEndpoint<List<Object>> implements ApplicationContextAware {
implements ApplicationContextAware {
private final HierarchyAwareLiveBeansView liveBeansView = new HierarchyAwareLiveBeansView(); private final HierarchyAwareLiveBeansView liveBeansView = new HierarchyAwareLiveBeansView();
@ -54,8 +53,7 @@ public class BeansEndpoint extends AbstractEndpoint<List<Object>>
@Override @Override
public void setApplicationContext(ApplicationContext context) throws BeansException { public void setApplicationContext(ApplicationContext context) throws BeansException {
if (context.getEnvironment() if (context.getEnvironment().getProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME) == null) {
.getProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME) == null) {
this.liveBeansView.setLeafContext(context); this.liveBeansView.setLeafContext(context);
} }
} }
@ -81,11 +79,9 @@ public class BeansEndpoint extends AbstractEndpoint<List<Object>>
return generateJson(getContextHierarchy()); return generateJson(getContextHierarchy());
} }
private ConfigurableApplicationContext asConfigurableContext( private ConfigurableApplicationContext asConfigurableContext(ApplicationContext applicationContext) {
ApplicationContext applicationContext) {
Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext, Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,
"'" + applicationContext "'" + applicationContext + "' does not implement ConfigurableApplicationContext");
+ "' does not implement ConfigurableApplicationContext");
return (ConfigurableApplicationContext) applicationContext; return (ConfigurableApplicationContext) applicationContext;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,8 +69,7 @@ public class CachePublicMetrics implements PublicMetrics {
@Override @Override
public Collection<Metric<?>> metrics() { public Collection<Metric<?>> metrics() {
Collection<Metric<?>> metrics = new HashSet<Metric<?>>(); Collection<Metric<?>> metrics = new HashSet<Metric<?>>();
for (Map.Entry<String, List<CacheManagerBean>> entry : getCacheManagerBeans() for (Map.Entry<String, List<CacheManagerBean>> entry : getCacheManagerBeans().entrySet()) {
.entrySet()) {
addMetrics(metrics, entry.getKey(), entry.getValue()); addMetrics(metrics, entry.getKey(), entry.getValue());
} }
return metrics; return metrics;
@ -80,15 +79,13 @@ public class CachePublicMetrics implements PublicMetrics {
MultiValueMap<String, CacheManagerBean> cacheManagerNamesByCacheName = new LinkedMultiValueMap<String, CacheManagerBean>(); MultiValueMap<String, CacheManagerBean> cacheManagerNamesByCacheName = new LinkedMultiValueMap<String, CacheManagerBean>();
for (Map.Entry<String, CacheManager> entry : this.cacheManagers.entrySet()) { for (Map.Entry<String, CacheManager> entry : this.cacheManagers.entrySet()) {
for (String cacheName : entry.getValue().getCacheNames()) { for (String cacheName : entry.getValue().getCacheNames()) {
cacheManagerNamesByCacheName.add(cacheName, cacheManagerNamesByCacheName.add(cacheName, new CacheManagerBean(entry.getKey(), entry.getValue()));
new CacheManagerBean(entry.getKey(), entry.getValue()));
} }
} }
return cacheManagerNamesByCacheName; return cacheManagerNamesByCacheName;
} }
private void addMetrics(Collection<Metric<?>> metrics, String cacheName, private void addMetrics(Collection<Metric<?>> metrics, String cacheName, List<CacheManagerBean> cacheManagerBeans) {
List<CacheManagerBean> cacheManagerBeans) {
for (CacheManagerBean cacheManagerBean : cacheManagerBeans) { for (CacheManagerBean cacheManagerBean : cacheManagerBeans) {
CacheManager cacheManager = cacheManagerBean.getCacheManager(); CacheManager cacheManager = cacheManagerBean.getCacheManager();
Cache cache = unwrapIfNecessary(cacheManager.getCache(cacheName)); Cache cache = unwrapIfNecessary(cacheManager.getCache(cacheName));
@ -105,8 +102,7 @@ public class CachePublicMetrics implements PublicMetrics {
} }
private Cache unwrapIfNecessary(Cache cache) { private Cache unwrapIfNecessary(Cache cache) {
if (ClassUtils.isPresent( if (ClassUtils.isPresent("org.springframework.cache.transaction.TransactionAwareCacheDecorator",
"org.springframework.cache.transaction.TransactionAwareCacheDecorator",
getClass().getClassLoader())) { getClass().getClassLoader())) {
return TransactionAwareCacheDecoratorHandler.unwrapIfNecessary(cache); return TransactionAwareCacheDecoratorHandler.unwrapIfNecessary(cache);
} }
@ -117,12 +113,10 @@ public class CachePublicMetrics implements PublicMetrics {
private CacheStatistics getCacheStatistics(Cache cache, CacheManager cacheManager) { private CacheStatistics getCacheStatistics(Cache cache, CacheManager cacheManager) {
if (this.statisticsProviders != null) { if (this.statisticsProviders != null) {
for (CacheStatisticsProvider provider : this.statisticsProviders) { for (CacheStatisticsProvider provider : this.statisticsProviders) {
Class<?> cacheType = ResolvableType Class<?> cacheType = ResolvableType.forClass(CacheStatisticsProvider.class, provider.getClass())
.forClass(CacheStatisticsProvider.class, provider.getClass())
.resolveGeneric(); .resolveGeneric();
if (cacheType.isInstance(cache)) { if (cacheType.isInstance(cache)) {
CacheStatistics statistics = provider.getCacheStatistics(cacheManager, CacheStatistics statistics = provider.getCacheStatistics(cacheManager, cache);
cache);
if (statistics != null) { if (statistics != null) {
return statistics; return statistics;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -65,8 +65,8 @@ import org.springframework.util.StringUtils;
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
@ConfigurationProperties(prefix = "endpoints.configprops") @ConfigurationProperties(prefix = "endpoints.configprops")
public class ConfigurationPropertiesReportEndpoint public class ConfigurationPropertiesReportEndpoint extends AbstractEndpoint<Map<String, Object>>
extends AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware { implements ApplicationContextAware {
private static final String CONFIGURATION_PROPERTIES_FILTER_ID = "configurationPropertiesFilter"; private static final String CONFIGURATION_PROPERTIES_FILTER_ID = "configurationPropertiesFilter";
@ -107,10 +107,8 @@ public class ConfigurationPropertiesReportEndpoint
private Map<String, Object> extract(ApplicationContext context, ObjectMapper mapper) { private Map<String, Object> extract(ApplicationContext context, ObjectMapper mapper) {
Map<String, Object> result = new HashMap<String, Object>(); Map<String, Object> result = new HashMap<String, Object>();
ConfigurationBeanFactoryMetaData beanFactoryMetaData = getBeanFactoryMetaData( ConfigurationBeanFactoryMetaData beanFactoryMetaData = getBeanFactoryMetaData(context);
context); Map<String, Object> beans = getConfigurationPropertiesBeans(context, beanFactoryMetaData);
Map<String, Object> beans = getConfigurationPropertiesBeans(context,
beanFactoryMetaData);
for (Map.Entry<String, Object> entry : beans.entrySet()) { for (Map.Entry<String, Object> entry : beans.entrySet()) {
String beanName = entry.getKey(); String beanName = entry.getKey();
Object bean = entry.getValue(); Object bean = entry.getValue();
@ -126,8 +124,7 @@ public class ConfigurationPropertiesReportEndpoint
return result; return result;
} }
private ConfigurationBeanFactoryMetaData getBeanFactoryMetaData( private ConfigurationBeanFactoryMetaData getBeanFactoryMetaData(ApplicationContext context) {
ApplicationContext context) {
Map<String, ConfigurationBeanFactoryMetaData> beans = context Map<String, ConfigurationBeanFactoryMetaData> beans = context
.getBeansOfType(ConfigurationBeanFactoryMetaData.class); .getBeansOfType(ConfigurationBeanFactoryMetaData.class);
if (beans.size() == 1) { if (beans.size() == 1) {
@ -136,14 +133,12 @@ public class ConfigurationPropertiesReportEndpoint
return null; return null;
} }
private Map<String, Object> getConfigurationPropertiesBeans( private Map<String, Object> getConfigurationPropertiesBeans(ApplicationContext context,
ApplicationContext context,
ConfigurationBeanFactoryMetaData beanFactoryMetaData) { ConfigurationBeanFactoryMetaData beanFactoryMetaData) {
Map<String, Object> beans = new HashMap<String, Object>(); Map<String, Object> beans = new HashMap<String, Object>();
beans.putAll(context.getBeansWithAnnotation(ConfigurationProperties.class)); beans.putAll(context.getBeansWithAnnotation(ConfigurationProperties.class));
if (beanFactoryMetaData != null) { if (beanFactoryMetaData != null) {
beans.putAll(beanFactoryMetaData beans.putAll(beanFactoryMetaData.getBeansWithFactoryAnnotation(ConfigurationProperties.class));
.getBeansWithFactoryAnnotation(ConfigurationProperties.class));
} }
return beans; return beans;
} }
@ -156,17 +151,15 @@ public class ConfigurationPropertiesReportEndpoint
* @param prefix the prefix * @param prefix the prefix
* @return the serialized instance * @return the serialized instance
*/ */
private Map<String, Object> safeSerialize(ObjectMapper mapper, Object bean, private Map<String, Object> safeSerialize(ObjectMapper mapper, Object bean, String prefix) {
String prefix) {
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, Object> result = new HashMap<String, Object>( Map<String, Object> result = new HashMap<String, Object>(mapper.convertValue(bean, Map.class));
mapper.convertValue(bean, Map.class));
return result; return result;
} }
catch (Exception ex) { catch (Exception ex) {
return new HashMap<String, Object>(Collections.<String, Object>singletonMap( return new HashMap<String, Object>(
"error", "Cannot serialize '" + prefix + "'")); Collections.<String, Object>singletonMap("error", "Cannot serialize '" + prefix + "'"));
} }
} }
@ -193,10 +186,9 @@ public class ConfigurationPropertiesReportEndpoint
} }
private void applyConfigurationPropertiesFilter(ObjectMapper mapper) { private void applyConfigurationPropertiesFilter(ObjectMapper mapper) {
mapper.setAnnotationIntrospector( mapper.setAnnotationIntrospector(new ConfigurationPropertiesAnnotationIntrospector());
new ConfigurationPropertiesAnnotationIntrospector()); mapper.setFilterProvider(
mapper.setFilterProvider(new SimpleFilterProvider() new SimpleFilterProvider().setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
.setDefaultFilter(new ConfigurationPropertiesPropertyFilter()));
} }
/** /**
@ -206,13 +198,12 @@ public class ConfigurationPropertiesReportEndpoint
* @param beanName the bean name * @param beanName the bean name
* @return the prefix * @return the prefix
*/ */
private String extractPrefix(ApplicationContext context, private String extractPrefix(ApplicationContext context, ConfigurationBeanFactoryMetaData beanFactoryMetaData,
ConfigurationBeanFactoryMetaData beanFactoryMetaData, String beanName) { String beanName) {
ConfigurationProperties annotation = context.findAnnotationOnBean(beanName, ConfigurationProperties annotation = context.findAnnotationOnBean(beanName, ConfigurationProperties.class);
ConfigurationProperties.class);
if (beanFactoryMetaData != null) { if (beanFactoryMetaData != null) {
ConfigurationProperties override = beanFactoryMetaData ConfigurationProperties override = beanFactoryMetaData.findFactoryAnnotation(beanName,
.findFactoryAnnotation(beanName, ConfigurationProperties.class); ConfigurationProperties.class);
if (override != null) { if (override != null) {
// The @Bean-level @ConfigurationProperties overrides the one at type // The @Bean-level @ConfigurationProperties overrides the one at type
// level when binding. Arguably we should render them both, but this one // level when binding. Arguably we should render them both, but this one
@ -273,8 +264,7 @@ public class ConfigurationPropertiesReportEndpoint
* properties. * properties.
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
private static class ConfigurationPropertiesAnnotationIntrospector private static class ConfigurationPropertiesAnnotationIntrospector extends JacksonAnnotationIntrospector {
extends JacksonAnnotationIntrospector {
@Override @Override
public Object findFilterId(Annotated a) { public Object findFilterId(Annotated a) {
@ -297,11 +287,9 @@ public class ConfigurationPropertiesReportEndpoint
* <li>Properties that throw an exception when retrieving their value. * <li>Properties that throw an exception when retrieving their value.
* </ul> * </ul>
*/ */
private static class ConfigurationPropertiesPropertyFilter private static class ConfigurationPropertiesPropertyFilter extends SimpleBeanPropertyFilter {
extends SimpleBeanPropertyFilter {
private static final Log logger = LogFactory private static final Log logger = LogFactory.getLog(ConfigurationPropertiesPropertyFilter.class);
.getLog(ConfigurationPropertiesPropertyFilter.class);
@Override @Override
protected boolean include(BeanPropertyWriter writer) { protected boolean include(BeanPropertyWriter writer) {
@ -318,14 +306,13 @@ public class ConfigurationPropertiesReportEndpoint
} }
@Override @Override
public void serializeAsField(Object pojo, JsonGenerator jgen, public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider,
SerializerProvider provider, PropertyWriter writer) throws Exception { PropertyWriter writer) throws Exception {
if (writer instanceof BeanPropertyWriter) { if (writer instanceof BeanPropertyWriter) {
try { try {
if (pojo == ((BeanPropertyWriter) writer).get(pojo)) { if (pojo == ((BeanPropertyWriter) writer).get(pojo)) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Skipping '" + writer.getFullName() + "' on '" logger.debug("Skipping '" + writer.getFullName() + "' on '" + pojo.getClass().getName()
+ pojo.getClass().getName()
+ "' as it is self-referential"); + "' as it is self-referential");
} }
return; return;
@ -333,9 +320,8 @@ public class ConfigurationPropertiesReportEndpoint
} }
catch (Exception ex) { catch (Exception ex) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Skipping '" + writer.getFullName() + "' on '" logger.debug("Skipping '" + writer.getFullName() + "' on '" + pojo.getClass().getName()
+ pojo.getClass().getName() + "' as an exception " + "' as an exception " + "was thrown when retrieving its value", ex);
+ "was thrown when retrieving its value", ex);
} }
return; return;
} }
@ -351,8 +337,8 @@ public class ConfigurationPropertiesReportEndpoint
protected static class GenericSerializerModifier extends BeanSerializerModifier { protected static class GenericSerializerModifier extends BeanSerializerModifier {
@Override @Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { List<BeanPropertyWriter> beanProperties) {
List<BeanPropertyWriter> result = new ArrayList<BeanPropertyWriter>(); List<BeanPropertyWriter> result = new ArrayList<BeanPropertyWriter>();
for (BeanPropertyWriter writer : beanProperties) { for (BeanPropertyWriter writer : beanProperties) {
boolean readable = isReadable(beanDesc, writer); boolean readable = isReadable(beanDesc, writer);
@ -373,15 +359,11 @@ public class ConfigurationPropertiesReportEndpoint
// should be kosher. Lists and Maps are also auto-detected by default since // should be kosher. Lists and Maps are also auto-detected by default since
// that's what the metadata generator does. This filter is not used if there // that's what the metadata generator does. This filter is not used if there
// is JSON metadata for the property, so it's mainly for user-defined beans. // is JSON metadata for the property, so it's mainly for user-defined beans.
return (setter != null) return (setter != null) || ClassUtils.getPackageName(parentType).equals(ClassUtils.getPackageName(type))
|| ClassUtils.getPackageName(parentType) || Map.class.isAssignableFrom(type) || Collection.class.isAssignableFrom(type);
.equals(ClassUtils.getPackageName(type))
|| Map.class.isAssignableFrom(type)
|| Collection.class.isAssignableFrom(type);
} }
private AnnotatedMethod findSetter(BeanDescription beanDesc, private AnnotatedMethod findSetter(BeanDescription beanDesc, BeanPropertyWriter writer) {
BeanPropertyWriter writer) {
String name = "set" + StringUtils.capitalize(writer.getName()); String name = "set" + StringUtils.capitalize(writer.getName());
Class<?> type = writer.getType().getRawClass(); Class<?> type = writer.getType().getRawClass();
AnnotatedMethod setter = beanDesc.findMethod(name, new Class<?>[] { type }); AnnotatedMethod setter = beanDesc.findMethod(name, new Class<?>[] { type });

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -56,15 +56,13 @@ public class DataSourcePublicMetrics implements PublicMetrics {
@PostConstruct @PostConstruct
public void initialize() { public void initialize() {
DataSource primaryDataSource = getPrimaryDataSource(); DataSource primaryDataSource = getPrimaryDataSource();
DataSourcePoolMetadataProvider provider = new DataSourcePoolMetadataProviders( DataSourcePoolMetadataProvider provider = new DataSourcePoolMetadataProviders(this.providers);
this.providers); for (Map.Entry<String, DataSource> entry : this.applicationContext.getBeansOfType(DataSource.class)
for (Map.Entry<String, DataSource> entry : this.applicationContext .entrySet()) {
.getBeansOfType(DataSource.class).entrySet()) {
String beanName = entry.getKey(); String beanName = entry.getKey();
DataSource bean = entry.getValue(); DataSource bean = entry.getValue();
String prefix = createPrefix(beanName, bean, bean.equals(primaryDataSource)); String prefix = createPrefix(beanName, bean, bean.equals(primaryDataSource));
DataSourcePoolMetadata poolMetadata = provider DataSourcePoolMetadata poolMetadata = provider.getDataSourcePoolMetadata(bean);
.getDataSourcePoolMetadata(bean);
if (poolMetadata != null) { if (poolMetadata != null) {
this.metadataByPrefix.put(prefix, poolMetadata); this.metadataByPrefix.put(prefix, poolMetadata);
} }
@ -74,8 +72,7 @@ public class DataSourcePublicMetrics implements PublicMetrics {
@Override @Override
public Collection<Metric<?>> metrics() { public Collection<Metric<?>> metrics() {
Set<Metric<?>> metrics = new LinkedHashSet<Metric<?>>(); Set<Metric<?>> metrics = new LinkedHashSet<Metric<?>>();
for (Map.Entry<String, DataSourcePoolMetadata> entry : this.metadataByPrefix for (Map.Entry<String, DataSourcePoolMetadata> entry : this.metadataByPrefix.entrySet()) {
.entrySet()) {
String prefix = entry.getKey(); String prefix = entry.getKey();
prefix = (prefix.endsWith(".") ? prefix : prefix + "."); prefix = (prefix.endsWith(".") ? prefix : prefix + ".");
DataSourcePoolMetadata metadata = entry.getValue(); DataSourcePoolMetadata metadata = entry.getValue();
@ -85,8 +82,7 @@ public class DataSourcePublicMetrics implements PublicMetrics {
return metrics; return metrics;
} }
private <T extends Number> void addMetric(Set<Metric<?>> metrics, String name, private <T extends Number> void addMetric(Set<Metric<?>> metrics, String name, T value) {
T value) {
if (value != null) { if (value != null) {
metrics.add(new Metric<T>(name, value)); metrics.add(new Metric<T>(name, value));
} }
@ -104,8 +100,8 @@ public class DataSourcePublicMetrics implements PublicMetrics {
if (primary) { if (primary) {
return "datasource.primary"; return "datasource.primary";
} }
if (name.length() > DATASOURCE_SUFFIX.length() && name.toLowerCase(Locale.ENGLISH) if (name.length() > DATASOURCE_SUFFIX.length()
.endsWith(DATASOURCE_SUFFIX.toLowerCase())) { && name.toLowerCase(Locale.ENGLISH).endsWith(DATASOURCE_SUFFIX.toLowerCase())) {
name = name.substring(0, name.length() - DATASOURCE_SUFFIX.length()); name = name.substring(0, name.length() - DATASOURCE_SUFFIX.length());
} }
return "datasource." + name; return "datasource." + name;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,8 +40,7 @@ public class DumpEndpoint extends AbstractEndpoint<List<ThreadInfo>> {
@Override @Override
public List<ThreadInfo> invoke() { public List<ThreadInfo> invoke() {
return Arrays return Arrays.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true));
.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,8 +69,7 @@ public class EndpointProperties {
if (enabled != null) { if (enabled != null) {
return enabled; return enabled;
} }
if (environment != null if (environment != null && environment.containsProperty(ENDPOINTS_ENABLED_PROPERTY)) {
&& environment.containsProperty(ENDPOINTS_ENABLED_PROPERTY)) {
return environment.getProperty(ENDPOINTS_ENABLED_PROPERTY, Boolean.class); return environment.getProperty(ENDPOINTS_ENABLED_PROPERTY, Boolean.class);
} }
return true; return true;
@ -85,13 +84,11 @@ public class EndpointProperties {
* defined * defined
* @return if the endpoint is sensitive * @return if the endpoint is sensitive
*/ */
public static boolean isSensitive(Environment environment, Boolean sensitive, public static boolean isSensitive(Environment environment, Boolean sensitive, boolean sensitiveDefault) {
boolean sensitiveDefault) {
if (sensitive != null) { if (sensitive != null) {
return sensitive; return sensitive;
} }
if (environment != null if (environment != null && environment.containsProperty(ENDPOINTS_SENSITIVE_PROPERTY)) {
&& environment.containsProperty(ENDPOINTS_SENSITIVE_PROPERTY)) {
return environment.getProperty(ENDPOINTS_SENSITIVE_PROPERTY, Boolean.class); return environment.getProperty(ENDPOINTS_SENSITIVE_PROPERTY, Boolean.class);
} }
return sensitiveDefault; return sensitiveDefault;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -61,8 +61,7 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
Map<String, Object> result = new LinkedHashMap<String, Object>(); Map<String, Object> result = new LinkedHashMap<String, Object>();
result.put("profiles", getEnvironment().getActiveProfiles()); result.put("profiles", getEnvironment().getActiveProfiles());
PropertyResolver resolver = getResolver(); PropertyResolver resolver = getResolver();
for (Entry<String, PropertySource<?>> entry : getPropertySourcesAsMap() for (Entry<String, PropertySource<?>> entry : getPropertySourcesAsMap().entrySet()) {
.entrySet()) {
PropertySource<?> source = entry.getValue(); PropertySource<?> source = entry.getValue();
String sourceName = entry.getKey(); String sourceName = entry.getKey();
if (source instanceof EnumerablePropertySource) { if (source instanceof EnumerablePropertySource) {
@ -85,8 +84,8 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
} }
public PropertyResolver getResolver() { public PropertyResolver getResolver() {
PlaceholderSanitizingPropertyResolver resolver = new PlaceholderSanitizingPropertyResolver( PlaceholderSanitizingPropertyResolver resolver = new PlaceholderSanitizingPropertyResolver(getPropertySources(),
getPropertySources(), this.sanitizer); this.sanitizer);
resolver.setIgnoreUnresolvableNestedPlaceholders(true); resolver.setIgnoreUnresolvableNestedPlaceholders(true);
return resolver; return resolver;
} }
@ -111,11 +110,9 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
return sources; return sources;
} }
private void extract(String root, Map<String, PropertySource<?>> map, private void extract(String root, Map<String, PropertySource<?>> map, PropertySource<?> source) {
PropertySource<?> source) {
if (source instanceof CompositePropertySource) { if (source instanceof CompositePropertySource) {
for (PropertySource<?> nest : ((CompositePropertySource) source) for (PropertySource<?> nest : ((CompositePropertySource) source).getPropertySources()) {
.getPropertySources()) {
extract(source.getName() + ":", map, nest); extract(source.getName() + ":", map, nest);
} }
} }
@ -136,8 +133,7 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
* added * added
* @since 1.4.0 * @since 1.4.0
*/ */
protected Map<String, Object> postProcessSourceProperties(String sourceName, protected Map<String, Object> postProcessSourceProperties(String sourceName, Map<String, Object> properties) {
Map<String, Object> properties) {
return properties; return properties;
} }
@ -145,8 +141,7 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
* {@link PropertySourcesPropertyResolver} that sanitizes sensitive placeholders if * {@link PropertySourcesPropertyResolver} that sanitizes sensitive placeholders if
* present. * present.
*/ */
private class PlaceholderSanitizingPropertyResolver private class PlaceholderSanitizingPropertyResolver extends PropertySourcesPropertyResolver {
extends PropertySourcesPropertyResolver {
private final Sanitizer sanitizer; private final Sanitizer sanitizer;
@ -155,8 +150,7 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
* @param propertySources the set of {@link PropertySource} objects to use * @param propertySources the set of {@link PropertySource} objects to use
* @param sanitizer the sanitizer used to sanitize sensitive values * @param sanitizer the sanitizer used to sanitize sensitive values
*/ */
PlaceholderSanitizingPropertyResolver(PropertySources propertySources, PlaceholderSanitizingPropertyResolver(PropertySources propertySources, Sanitizer sanitizer) {
Sanitizer sanitizer) {
super(propertySources); super(propertySources);
this.sanitizer = sanitizer; this.sanitizer = sanitizer;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -48,13 +48,11 @@ public class HealthEndpoint extends AbstractEndpoint<Health> {
* @param healthAggregator the health aggregator * @param healthAggregator the health aggregator
* @param healthIndicators the health indicators * @param healthIndicators the health indicators
*/ */
public HealthEndpoint(HealthAggregator healthAggregator, public HealthEndpoint(HealthAggregator healthAggregator, Map<String, HealthIndicator> healthIndicators) {
Map<String, HealthIndicator> healthIndicators) {
super("health", false); super("health", false);
Assert.notNull(healthAggregator, "HealthAggregator must not be null"); Assert.notNull(healthAggregator, "HealthAggregator must not be null");
Assert.notNull(healthIndicators, "HealthIndicators must not be null"); Assert.notNull(healthIndicators, "HealthIndicators must not be null");
CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator( CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator(healthAggregator);
healthAggregator);
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) { for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
healthIndicator.addHealthIndicator(getKey(entry.getKey()), entry.getValue()); healthIndicator.addHealthIndicator(getKey(entry.getKey()), entry.getValue());
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -64,8 +64,7 @@ public class LiquibaseEndpoint extends AbstractEndpoint<List<LiquibaseReport>> {
for (Map.Entry<String, SpringLiquibase> entry : this.liquibases.entrySet()) { for (Map.Entry<String, SpringLiquibase> entry : this.liquibases.entrySet()) {
try { try {
DataSource dataSource = entry.getValue().getDataSource(); DataSource dataSource = entry.getValue().getDataSource();
JdbcConnection connection = new JdbcConnection( JdbcConnection connection = new JdbcConnection(dataSource.getConnection());
dataSource.getConnection());
Database database = null; Database database = null;
try { try {
database = factory.findCorrectDatabaseImplementation(connection); database = factory.findCorrectDatabaseImplementation(connection);
@ -73,8 +72,7 @@ public class LiquibaseEndpoint extends AbstractEndpoint<List<LiquibaseReport>> {
if (StringUtils.hasText(defaultSchema)) { if (StringUtils.hasText(defaultSchema)) {
database.setDefaultSchemaName(defaultSchema); database.setDefaultSchemaName(defaultSchema);
} }
reports.add(new LiquibaseReport(entry.getKey(), reports.add(new LiquibaseReport(entry.getKey(), service.queryDatabaseChangeLogTable(database)));
service.queryDatabaseChangeLogTable(database)));
} }
finally { finally {
if (database != null) { if (database != null) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -54,8 +54,7 @@ public class LoggersEndpoint extends AbstractEndpoint<Map<String, Object>> {
@Override @Override
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
Collection<LoggerConfiguration> configurations = this.loggingSystem Collection<LoggerConfiguration> configurations = this.loggingSystem.getLoggerConfigurations();
.getLoggerConfigurations();
if (configurations == null) { if (configurations == null) {
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -70,10 +69,8 @@ public class LoggersEndpoint extends AbstractEndpoint<Map<String, Object>> {
return new TreeSet<LogLevel>(levels).descendingSet(); return new TreeSet<LogLevel>(levels).descendingSet();
} }
private Map<String, LoggerLevels> getLoggers( private Map<String, LoggerLevels> getLoggers(Collection<LoggerConfiguration> configurations) {
Collection<LoggerConfiguration> configurations) { Map<String, LoggerLevels> loggers = new LinkedHashMap<String, LoggerLevels>(configurations.size());
Map<String, LoggerLevels> loggers = new LinkedHashMap<String, LoggerLevels>(
configurations.size());
for (LoggerConfiguration configuration : configurations) { for (LoggerConfiguration configuration : configurations) {
loggers.put(configuration.getName(), new LoggerLevels(configuration)); loggers.put(configuration.getName(), new LoggerLevels(configuration));
} }
@ -82,8 +79,7 @@ public class LoggersEndpoint extends AbstractEndpoint<Map<String, Object>> {
public LoggerLevels invoke(String name) { public LoggerLevels invoke(String name) {
Assert.notNull(name, "Name must not be null"); Assert.notNull(name, "Name must not be null");
LoggerConfiguration configuration = this.loggingSystem LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
.getLoggerConfiguration(name);
return (configuration != null) ? new LoggerLevels(configuration) : null; return (configuration != null) ? new LoggerLevels(configuration) : null;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,13 +39,11 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@ConfigurationProperties(prefix = "endpoints.mappings") @ConfigurationProperties(prefix = "endpoints.mappings")
public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>> public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware {
implements ApplicationContextAware {
private List<AbstractUrlHandlerMapping> handlerMappings = Collections.emptyList(); private List<AbstractUrlHandlerMapping> handlerMappings = Collections.emptyList();
private List<AbstractHandlerMethodMapping<?>> methodMappings = Collections private List<AbstractHandlerMethodMapping<?>> methodMappings = Collections.emptyList();
.emptyList();
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@ -54,8 +52,7 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
} }
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
throws BeansException {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }
@ -86,8 +83,7 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
protected void extractMethodMappings(ApplicationContext applicationContext, protected void extractMethodMappings(ApplicationContext applicationContext, Map<String, Object> result) {
Map<String, Object> result) {
if (applicationContext != null) { if (applicationContext != null) {
for (Entry<String, AbstractHandlerMethodMapping> bean : applicationContext for (Entry<String, AbstractHandlerMethodMapping> bean : applicationContext
.getBeansOfType(AbstractHandlerMethodMapping.class).entrySet()) { .getBeansOfType(AbstractHandlerMethodMapping.class).entrySet()) {
@ -103,16 +99,14 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
} }
} }
protected void extractHandlerMappings(ApplicationContext applicationContext, protected void extractHandlerMappings(ApplicationContext applicationContext, Map<String, Object> result) {
Map<String, Object> result) {
if (applicationContext != null) { if (applicationContext != null) {
Map<String, AbstractUrlHandlerMapping> mappings = applicationContext Map<String, AbstractUrlHandlerMapping> mappings = applicationContext
.getBeansOfType(AbstractUrlHandlerMapping.class); .getBeansOfType(AbstractUrlHandlerMapping.class);
for (Entry<String, AbstractUrlHandlerMapping> mapping : mappings.entrySet()) { for (Entry<String, AbstractUrlHandlerMapping> mapping : mappings.entrySet()) {
Map<String, Object> handlers = getHandlerMap(mapping.getValue()); Map<String, Object> handlers = getHandlerMap(mapping.getValue());
for (Entry<String, Object> handler : handlers.entrySet()) { for (Entry<String, Object> handler : handlers.entrySet()) {
result.put(handler.getKey(), result.put(handler.getKey(), Collections.singletonMap("bean", mapping.getKey()));
Collections.singletonMap("bean", mapping.getKey()));
} }
} }
} }
@ -127,27 +121,24 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
return mapping.getHandlerMap(); return mapping.getHandlerMap();
} }
protected void extractHandlerMappings( protected void extractHandlerMappings(Collection<AbstractUrlHandlerMapping> handlerMappings,
Collection<AbstractUrlHandlerMapping> handlerMappings,
Map<String, Object> result) { Map<String, Object> result) {
for (AbstractUrlHandlerMapping mapping : handlerMappings) { for (AbstractUrlHandlerMapping mapping : handlerMappings) {
Map<String, Object> handlers = mapping.getHandlerMap(); Map<String, Object> handlers = mapping.getHandlerMap();
for (Map.Entry<String, Object> entry : handlers.entrySet()) { for (Map.Entry<String, Object> entry : handlers.entrySet()) {
Class<? extends Object> handlerClass = entry.getValue().getClass(); Class<? extends Object> handlerClass = entry.getValue().getClass();
result.put(entry.getKey(), result.put(entry.getKey(), Collections.singletonMap("type", handlerClass.getName()));
Collections.singletonMap("type", handlerClass.getName()));
} }
} }
} }
protected void extractMethodMappings( protected void extractMethodMappings(Collection<AbstractHandlerMethodMapping<?>> methodMappings,
Collection<AbstractHandlerMethodMapping<?>> methodMappings,
Map<String, Object> result) { Map<String, Object> result) {
for (AbstractHandlerMethodMapping<?> mapping : methodMappings) { for (AbstractHandlerMethodMapping<?> mapping : methodMappings) {
Map<?, HandlerMethod> methods = mapping.getHandlerMethods(); Map<?, HandlerMethod> methods = mapping.getHandlerMethods();
for (Map.Entry<?, HandlerMethod> entry : methods.entrySet()) { for (Map.Entry<?, HandlerMethod> entry : methods.entrySet()) {
result.put(String.valueOf(entry.getKey()), Collections result.put(String.valueOf(entry.getKey()),
.singletonMap("method", String.valueOf(entry.getValue()))); Collections.singletonMap("method", String.valueOf(entry.getValue())));
} }
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -51,13 +51,11 @@ public class RichGaugeReaderPublicMetrics implements PublicMetrics {
private List<Metric<?>> convert(RichGauge gauge) { private List<Metric<?>> convert(RichGauge gauge) {
List<Metric<?>> result = new ArrayList<Metric<?>>(6); List<Metric<?>> result = new ArrayList<Metric<?>>(6);
result.add( result.add(new Metric<Double>(gauge.getName() + RichGauge.AVG, gauge.getAverage()));
new Metric<Double>(gauge.getName() + RichGauge.AVG, gauge.getAverage()));
result.add(new Metric<Double>(gauge.getName() + RichGauge.VAL, gauge.getValue())); result.add(new Metric<Double>(gauge.getName() + RichGauge.VAL, gauge.getValue()));
result.add(new Metric<Double>(gauge.getName() + RichGauge.MIN, gauge.getMin())); result.add(new Metric<Double>(gauge.getName() + RichGauge.MIN, gauge.getMin()));
result.add(new Metric<Double>(gauge.getName() + RichGauge.MAX, gauge.getMax())); result.add(new Metric<Double>(gauge.getName() + RichGauge.MAX, gauge.getMax()));
result.add( result.add(new Metric<Double>(gauge.getName() + RichGauge.ALPHA, gauge.getAlpha()));
new Metric<Double>(gauge.getName() + RichGauge.ALPHA, gauge.getAlpha()));
result.add(new Metric<Long>(gauge.getName() + RichGauge.COUNT, gauge.getCount())); result.add(new Metric<Long>(gauge.getName() + RichGauge.COUNT, gauge.getCount()));
return result; return result;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,8 +36,7 @@ class Sanitizer {
private Pattern[] keysToSanitize; private Pattern[] keysToSanitize;
Sanitizer() { Sanitizer() {
this("password", "secret", "key", "token", ".*credentials.*", "vcap_services", this("password", "secret", "key", "token", ".*credentials.*", "vcap_services", "sun.java.command");
"sun.java.command");
} }
Sanitizer(String... keysToSanitize) { Sanitizer(String... keysToSanitize) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,16 +33,13 @@ import org.springframework.context.ConfigurableApplicationContext;
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@ConfigurationProperties(prefix = "endpoints.shutdown") @ConfigurationProperties(prefix = "endpoints.shutdown")
public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware {
implements ApplicationContextAware {
private static final Map<String, Object> NO_CONTEXT_MESSAGE = Collections private static final Map<String, Object> NO_CONTEXT_MESSAGE = Collections
.unmodifiableMap(Collections.<String, Object>singletonMap("message", .unmodifiableMap(Collections.<String, Object>singletonMap("message", "No context to shutdown."));
"No context to shutdown."));
private static final Map<String, Object> SHUTDOWN_MESSAGE = Collections private static final Map<String, Object> SHUTDOWN_MESSAGE = Collections
.unmodifiableMap(Collections.<String, Object>singletonMap("message", .unmodifiableMap(Collections.<String, Object>singletonMap("message", "Shutting down, bye..."));
"Shutting down, bye..."));
private ConfigurableApplicationContext context; private ConfigurableApplicationContext context;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -67,12 +67,10 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
protected void addBasicMetrics(Collection<Metric<?>> result) { protected void addBasicMetrics(Collection<Metric<?>> result) {
// NOTE: ManagementFactory must not be used here since it fails on GAE // NOTE: ManagementFactory must not be used here since it fails on GAE
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
result.add(newMemoryMetric("mem", result.add(newMemoryMetric("mem", runtime.totalMemory() + getTotalNonHeapMemoryIfPossible()));
runtime.totalMemory() + getTotalNonHeapMemoryIfPossible()));
result.add(newMemoryMetric("mem.free", runtime.freeMemory())); result.add(newMemoryMetric("mem.free", runtime.freeMemory()));
result.add(new Metric<Integer>("processors", runtime.availableProcessors())); result.add(new Metric<Integer>("processors", runtime.availableProcessors()));
result.add(new Metric<Long>("instance.uptime", result.add(new Metric<Long>("instance.uptime", System.currentTimeMillis() - this.timestamp));
System.currentTimeMillis() - this.timestamp));
} }
private long getTotalNonHeapMemoryIfPossible() { private long getTotalNonHeapMemoryIfPossible() {
@ -92,8 +90,7 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
private void addManagementMetrics(Collection<Metric<?>> result) { private void addManagementMetrics(Collection<Metric<?>> result) {
try { try {
// Add JVM up time in ms // Add JVM up time in ms
result.add(new Metric<Long>("uptime", result.add(new Metric<Long>("uptime", ManagementFactory.getRuntimeMXBean().getUptime()));
ManagementFactory.getRuntimeMXBean().getUptime()));
result.add(new Metric<Double>("systemload.average", result.add(new Metric<Double>("systemload.average",
ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage())); ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()));
addHeapMetrics(result); addHeapMetrics(result);
@ -112,8 +109,7 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
* @param result the result * @param result the result
*/ */
protected void addHeapMetrics(Collection<Metric<?>> result) { protected void addHeapMetrics(Collection<Metric<?>> result) {
MemoryUsage memoryUsage = ManagementFactory.getMemoryMXBean() MemoryUsage memoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
.getHeapMemoryUsage();
result.add(newMemoryMetric("heap.committed", memoryUsage.getCommitted())); result.add(newMemoryMetric("heap.committed", memoryUsage.getCommitted()));
result.add(newMemoryMetric("heap.init", memoryUsage.getInit())); result.add(newMemoryMetric("heap.init", memoryUsage.getInit()));
result.add(newMemoryMetric("heap.used", memoryUsage.getUsed())); result.add(newMemoryMetric("heap.used", memoryUsage.getUsed()));
@ -125,8 +121,7 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
* @param result the result * @param result the result
*/ */
private void addNonHeapMetrics(Collection<Metric<?>> result) { private void addNonHeapMetrics(Collection<Metric<?>> result) {
MemoryUsage memoryUsage = ManagementFactory.getMemoryMXBean() MemoryUsage memoryUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
.getNonHeapMemoryUsage();
result.add(newMemoryMetric("nonheap.committed", memoryUsage.getCommitted())); result.add(newMemoryMetric("nonheap.committed", memoryUsage.getCommitted()));
result.add(newMemoryMetric("nonheap.init", memoryUsage.getInit())); result.add(newMemoryMetric("nonheap.init", memoryUsage.getInit()));
result.add(newMemoryMetric("nonheap.used", memoryUsage.getUsed())); result.add(newMemoryMetric("nonheap.used", memoryUsage.getUsed()));
@ -143,12 +138,9 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
*/ */
protected void addThreadMetrics(Collection<Metric<?>> result) { protected void addThreadMetrics(Collection<Metric<?>> result) {
ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
result.add(new Metric<Long>("threads.peak", result.add(new Metric<Long>("threads.peak", (long) threadMxBean.getPeakThreadCount()));
(long) threadMxBean.getPeakThreadCount())); result.add(new Metric<Long>("threads.daemon", (long) threadMxBean.getDaemonThreadCount()));
result.add(new Metric<Long>("threads.daemon", result.add(new Metric<Long>("threads.totalStarted", threadMxBean.getTotalStartedThreadCount()));
(long) threadMxBean.getDaemonThreadCount()));
result.add(new Metric<Long>("threads.totalStarted",
threadMxBean.getTotalStartedThreadCount()));
result.add(new Metric<Long>("threads", (long) threadMxBean.getThreadCount())); result.add(new Metric<Long>("threads", (long) threadMxBean.getThreadCount()));
} }
@ -158,12 +150,9 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
*/ */
protected void addClassLoadingMetrics(Collection<Metric<?>> result) { protected void addClassLoadingMetrics(Collection<Metric<?>> result) {
ClassLoadingMXBean classLoadingMxBean = ManagementFactory.getClassLoadingMXBean(); ClassLoadingMXBean classLoadingMxBean = ManagementFactory.getClassLoadingMXBean();
result.add(new Metric<Long>("classes", result.add(new Metric<Long>("classes", (long) classLoadingMxBean.getLoadedClassCount()));
(long) classLoadingMxBean.getLoadedClassCount())); result.add(new Metric<Long>("classes.loaded", classLoadingMxBean.getTotalLoadedClassCount()));
result.add(new Metric<Long>("classes.loaded", result.add(new Metric<Long>("classes.unloaded", classLoadingMxBean.getUnloadedClassCount()));
classLoadingMxBean.getTotalLoadedClassCount()));
result.add(new Metric<Long>("classes.unloaded",
classLoadingMxBean.getUnloadedClassCount()));
} }
/** /**
@ -171,14 +160,11 @@ public class SystemPublicMetrics implements PublicMetrics, Ordered {
* @param result the result * @param result the result
*/ */
protected void addGarbageCollectionMetrics(Collection<Metric<?>> result) { protected void addGarbageCollectionMetrics(Collection<Metric<?>> result) {
List<GarbageCollectorMXBean> garbageCollectorMxBeans = ManagementFactory List<GarbageCollectorMXBean> garbageCollectorMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMxBeans) { for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMxBeans) {
String name = beautifyGcName(garbageCollectorMXBean.getName()); String name = beautifyGcName(garbageCollectorMXBean.getName());
result.add(new Metric<Long>("gc." + name + ".count", result.add(new Metric<Long>("gc." + name + ".count", garbageCollectorMXBean.getCollectionCount()));
garbageCollectorMXBean.getCollectionCount())); result.add(new Metric<Long>("gc." + name + ".time", garbageCollectorMXBean.getCollectionTime()));
result.add(new Metric<Long>("gc." + name + ".time",
garbageCollectorMXBean.getCollectionTime()));
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -48,8 +48,7 @@ public class TomcatPublicMetrics implements PublicMetrics, ApplicationContextAwa
@Override @Override
public Collection<Metric<?>> metrics() { public Collection<Metric<?>> metrics() {
if (this.applicationContext instanceof EmbeddedWebApplicationContext) { if (this.applicationContext instanceof EmbeddedWebApplicationContext) {
Manager manager = getManager( Manager manager = getManager((EmbeddedWebApplicationContext) this.applicationContext);
(EmbeddedWebApplicationContext) this.applicationContext);
if (manager != null) { if (manager != null) {
return metrics(manager); return metrics(manager);
} }
@ -58,8 +57,7 @@ public class TomcatPublicMetrics implements PublicMetrics, ApplicationContextAwa
} }
private Manager getManager(EmbeddedWebApplicationContext applicationContext) { private Manager getManager(EmbeddedWebApplicationContext applicationContext) {
EmbeddedServletContainer embeddedServletContainer = applicationContext EmbeddedServletContainer embeddedServletContainer = applicationContext.getEmbeddedServletContainer();
.getEmbeddedServletContainer();
if (embeddedServletContainer instanceof TomcatEmbeddedServletContainer) { if (embeddedServletContainer instanceof TomcatEmbeddedServletContainer) {
return getManager((TomcatEmbeddedServletContainer) embeddedServletContainer); return getManager((TomcatEmbeddedServletContainer) embeddedServletContainer);
} }
@ -67,8 +65,7 @@ public class TomcatPublicMetrics implements PublicMetrics, ApplicationContextAwa
} }
private Manager getManager(TomcatEmbeddedServletContainer servletContainer) { private Manager getManager(TomcatEmbeddedServletContainer servletContainer) {
for (Container container : servletContainer.getTomcat().getHost() for (Container container : servletContainer.getTomcat().getHost().findChildren()) {
.findChildren()) {
if (container instanceof Context) { if (container instanceof Context) {
return ((Context) container).getManager(); return ((Context) container).getManager();
} }
@ -79,8 +76,7 @@ public class TomcatPublicMetrics implements PublicMetrics, ApplicationContextAwa
private Collection<Metric<?>> metrics(Manager manager) { private Collection<Metric<?>> metrics(Manager manager) {
List<Metric<?>> metrics = new ArrayList<Metric<?>>(2); List<Metric<?>> metrics = new ArrayList<Metric<?>>(2);
if (manager instanceof ManagerBase) { if (manager instanceof ManagerBase) {
addMetric(metrics, "httpsessions.max", addMetric(metrics, "httpsessions.max", ((ManagerBase) manager).getMaxActiveSessions());
((ManagerBase) manager).getMaxActiveSessions());
} }
addMetric(metrics, "httpsessions.active", manager.getActiveSessions()); addMetric(metrics, "httpsessions.active", manager.getActiveSessions());
return metrics; return metrics;
@ -91,8 +87,7 @@ public class TomcatPublicMetrics implements PublicMetrics, ApplicationContextAwa
} }
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
throws BeansException {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }

@ -41,34 +41,27 @@ public class AuditEventsJmxEndpoint extends AbstractJmxEndpoint {
private final AuditEventRepository auditEventRepository; private final AuditEventRepository auditEventRepository;
public AuditEventsJmxEndpoint(ObjectMapper objectMapper, public AuditEventsJmxEndpoint(ObjectMapper objectMapper, AuditEventRepository auditEventRepository) {
AuditEventRepository auditEventRepository) {
super(objectMapper); super(objectMapper);
Assert.notNull(auditEventRepository, "AuditEventRepository must not be null"); Assert.notNull(auditEventRepository, "AuditEventRepository must not be null");
this.auditEventRepository = auditEventRepository; this.auditEventRepository = auditEventRepository;
} }
@ManagedOperation( @ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
description = "Retrieves a list of audit events meeting the given criteria")
public Object getData(String dateAfter) { public Object getData(String dateAfter) {
List<AuditEvent> auditEvents = this.auditEventRepository List<AuditEvent> auditEvents = this.auditEventRepository.find(parseDate(dateAfter));
.find(parseDate(dateAfter));
return convert(auditEvents); return convert(auditEvents);
} }
@ManagedOperation( @ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
description = "Retrieves a list of audit events meeting the given criteria")
public Object getData(String dateAfter, String principal) { public Object getData(String dateAfter, String principal) {
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, parseDate(dateAfter));
parseDate(dateAfter));
return convert(auditEvents); return convert(auditEvents);
} }
@ManagedOperation( @ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
description = "Retrieves a list of audit events meeting the given criteria")
public Object getData(String principal, String dateAfter, String type) { public Object getData(String principal, String dateAfter, String type) {
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, parseDate(dateAfter), type);
parseDate(dateAfter), type);
return convert(auditEvents); return convert(auditEvents);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,10 +39,9 @@ class DataConverter {
DataConverter(ObjectMapper objectMapper) { DataConverter(ObjectMapper objectMapper) {
this.objectMapper = (objectMapper != null) ? objectMapper : new ObjectMapper(); this.objectMapper = (objectMapper != null) ? objectMapper : new ObjectMapper();
this.listObject = this.objectMapper.getTypeFactory() this.listObject = this.objectMapper.getTypeFactory().constructParametricType(List.class, Object.class);
.constructParametricType(List.class, Object.class); this.mapStringObject = this.objectMapper.getTypeFactory().constructParametricType(Map.class, String.class,
this.mapStringObject = this.objectMapper.getTypeFactory() Object.class);
.constructParametricType(Map.class, String.class, Object.class);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,8 +36,7 @@ public class DataEndpointMBean extends EndpointMBean {
* @param endpoint the endpoint to wrap * @param endpoint the endpoint to wrap
* @param objectMapper the {@link ObjectMapper} used to convert the payload * @param objectMapper the {@link ObjectMapper} used to convert the payload
*/ */
public DataEndpointMBean(String beanName, Endpoint<?> endpoint, public DataEndpointMBean(String beanName, Endpoint<?> endpoint, ObjectMapper objectMapper) {
ObjectMapper objectMapper) {
super(beanName, endpoint, objectMapper); super(beanName, endpoint, objectMapper);
} }

@ -46,8 +46,7 @@ public abstract class EndpointMBean implements JmxEndpoint {
* @param endpoint the endpoint to wrap * @param endpoint the endpoint to wrap
* @param objectMapper the {@link ObjectMapper} used to convert the payload * @param objectMapper the {@link ObjectMapper} used to convert the payload
*/ */
public EndpointMBean(String beanName, Endpoint<?> endpoint, public EndpointMBean(String beanName, Endpoint<?> endpoint, ObjectMapper objectMapper) {
ObjectMapper objectMapper) {
this.dataConverter = new DataConverter(objectMapper); this.dataConverter = new DataConverter(objectMapper);
Assert.notNull(beanName, "BeanName must not be null"); Assert.notNull(beanName, "BeanName must not be null");
Assert.notNull(endpoint, "Endpoint must not be null"); Assert.notNull(endpoint, "Endpoint must not be null");
@ -64,8 +63,7 @@ public abstract class EndpointMBean implements JmxEndpoint {
return this.endpoint.isEnabled(); return this.endpoint.isEnabled();
} }
@ManagedAttribute( @ManagedAttribute(description = "Indicates whether the underlying endpoint exposes sensitive information")
description = "Indicates whether the underlying endpoint exposes sensitive information")
public boolean isSensitive() { public boolean isSensitive() {
return this.endpoint.isSensitive(); return this.endpoint.isSensitive();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,8 +63,7 @@ import org.springframework.util.ObjectUtils;
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Vedran Pavic * @author Vedran Pavic
*/ */
public class EndpointMBeanExporter extends MBeanExporter public class EndpointMBeanExporter extends MBeanExporter implements SmartLifecycle, ApplicationContextAware {
implements SmartLifecycle, ApplicationContextAware {
/** /**
* The default JMX domain. * The default JMX domain.
@ -75,11 +74,9 @@ public class EndpointMBeanExporter extends MBeanExporter
private final AnnotationJmxAttributeSource attributeSource = new EndpointJmxAttributeSource(); private final AnnotationJmxAttributeSource attributeSource = new EndpointJmxAttributeSource();
private final MetadataMBeanInfoAssembler assembler = new MetadataMBeanInfoAssembler( private final MetadataMBeanInfoAssembler assembler = new MetadataMBeanInfoAssembler(this.attributeSource);
this.attributeSource);
private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy( private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy(this.attributeSource);
this.attributeSource);
private final Set<Class<?>> registeredEndpoints = new HashSet<Class<?>>(); private final Set<Class<?>> registeredEndpoints = new HashSet<Class<?>>();
@ -122,8 +119,7 @@ public class EndpointMBeanExporter extends MBeanExporter
} }
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
throws BeansException {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }
@ -144,8 +140,7 @@ public class EndpointMBeanExporter extends MBeanExporter
} }
@Override @Override
public void setEnsureUniqueRuntimeObjectNames( public void setEnsureUniqueRuntimeObjectNames(boolean ensureUniqueRuntimeObjectNames) {
boolean ensureUniqueRuntimeObjectNames) {
super.setEnsureUniqueRuntimeObjectNames(ensureUniqueRuntimeObjectNames); super.setEnsureUniqueRuntimeObjectNames(ensureUniqueRuntimeObjectNames);
this.ensureUniqueRuntimeObjectNames = ensureUniqueRuntimeObjectNames; this.ensureUniqueRuntimeObjectNames = ensureUniqueRuntimeObjectNames;
} }
@ -167,8 +162,7 @@ public class EndpointMBeanExporter extends MBeanExporter
for (Map.Entry<String, JmxEndpoint> entry : endpoints.entrySet()) { for (Map.Entry<String, JmxEndpoint> entry : endpoints.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
JmxEndpoint endpoint = entry.getValue(); JmxEndpoint endpoint = entry.getValue();
Class<?> type = (endpoint.getEndpointType() != null) Class<?> type = (endpoint.getEndpointType() != null) ? endpoint.getEndpointType() : endpoint.getClass();
? endpoint.getEndpointType() : endpoint.getClass();
if (!this.registeredEndpoints.contains(type) && endpoint.isEnabled()) { if (!this.registeredEndpoints.contains(type) && endpoint.isEnabled()) {
try { try {
registerBeanNameOrInstance(endpoint, name); registerBeanNameOrInstance(endpoint, name);
@ -204,8 +198,8 @@ public class EndpointMBeanExporter extends MBeanExporter
@Deprecated @Deprecated
protected void registerEndpoint(String beanName, Endpoint<?> endpoint) { protected void registerEndpoint(String beanName, Endpoint<?> endpoint) {
Class<?> type = endpoint.getClass(); Class<?> type = endpoint.getClass();
if (isAnnotatedWithManagedResource(type) || (type.isMemberClass() if (isAnnotatedWithManagedResource(type)
&& isAnnotatedWithManagedResource(type.getEnclosingClass()))) { || (type.isMemberClass() && isAnnotatedWithManagedResource(type.getEnclosingClass()))) {
// Endpoint is directly managed // Endpoint is directly managed
return; return;
} }
@ -251,8 +245,7 @@ public class EndpointMBeanExporter extends MBeanExporter
} }
@Override @Override
protected ObjectName getObjectName(Object bean, String beanKey) protected ObjectName getObjectName(Object bean, String beanKey) throws MalformedObjectNameException {
throws MalformedObjectNameException {
if (bean instanceof SelfNaming) { if (bean instanceof SelfNaming) {
return ((SelfNaming) bean).getObjectName(); return ((SelfNaming) bean).getObjectName();
} }
@ -262,15 +255,13 @@ public class EndpointMBeanExporter extends MBeanExporter
return this.defaultNamingStrategy.getObjectName(bean, beanKey); return this.defaultNamingStrategy.getObjectName(bean, beanKey);
} }
private ObjectName getObjectName(JmxEndpoint jmxEndpoint, String beanKey) private ObjectName getObjectName(JmxEndpoint jmxEndpoint, String beanKey) throws MalformedObjectNameException {
throws MalformedObjectNameException {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append(this.domain); builder.append(this.domain);
builder.append(":type=Endpoint"); builder.append(":type=Endpoint");
builder.append(",name=" + beanKey); builder.append(",name=" + beanKey);
if (parentContextContainsSameBean(this.applicationContext, beanKey)) { if (parentContextContainsSameBean(this.applicationContext, beanKey)) {
builder.append(",context=" builder.append(",context=" + ObjectUtils.getIdentityHexString(this.applicationContext));
+ ObjectUtils.getIdentityHexString(this.applicationContext));
} }
if (this.ensureUniqueRuntimeObjectNames) { if (this.ensureUniqueRuntimeObjectNames) {
builder.append(",identity=" + jmxEndpoint.getIdentity()); builder.append(",identity=" + jmxEndpoint.getIdentity());
@ -279,8 +270,7 @@ public class EndpointMBeanExporter extends MBeanExporter
return ObjectNameManager.getInstance(builder.toString()); return ObjectNameManager.getInstance(builder.toString());
} }
private boolean parentContextContainsSameBean(ApplicationContext applicationContext, private boolean parentContextContainsSameBean(ApplicationContext applicationContext, String beanKey) {
String beanKey) {
if (applicationContext.getParent() != null) { if (applicationContext.getParent() != null) {
try { try {
Object bean = this.applicationContext.getParent().getBean(beanKey); Object bean = this.applicationContext.getParent().getBean(beanKey);
@ -374,8 +364,8 @@ public class EndpointMBeanExporter extends MBeanExporter
private static class EndpointJmxAttributeSource extends AnnotationJmxAttributeSource { private static class EndpointJmxAttributeSource extends AnnotationJmxAttributeSource {
@Override @Override
public org.springframework.jmx.export.metadata.ManagedResource getManagedResource( public org.springframework.jmx.export.metadata.ManagedResource getManagedResource(Class<?> beanClass)
Class<?> beanClass) throws InvalidMetadataException { throws InvalidMetadataException {
Assert.state(super.getManagedResource(beanClass) == null, Assert.state(super.getManagedResource(beanClass) == null,
"@ManagedResource annotation found on JmxEndpoint " + beanClass); "@ManagedResource annotation found on JmxEndpoint " + beanClass);
return new org.springframework.jmx.export.metadata.ManagedResource(); return new org.springframework.jmx.export.metadata.ManagedResource();

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,8 +36,7 @@ import org.springframework.util.Assert;
*/ */
public class LoggersEndpointMBean extends EndpointMBean { public class LoggersEndpointMBean extends EndpointMBean {
public LoggersEndpointMBean(String beanName, Endpoint<?> endpoint, public LoggersEndpointMBean(String beanName, Endpoint<?> endpoint, ObjectMapper objectMapper) {
ObjectMapper objectMapper) {
super(beanName, endpoint, objectMapper); super(beanName, endpoint, objectMapper);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,8 +36,7 @@ public class ShutdownEndpointMBean extends EndpointMBean {
* @param endpoint the endpoint to wrap * @param endpoint the endpoint to wrap
* @param objectMapper the {@link ObjectMapper} used to convert the payload * @param objectMapper the {@link ObjectMapper} used to convert the payload
*/ */
public ShutdownEndpointMBean(String beanName, Endpoint<?> endpoint, public ShutdownEndpointMBean(String beanName, Endpoint<?> endpoint, ObjectMapper objectMapper) {
ObjectMapper objectMapper) {
super(beanName, endpoint, objectMapper); super(beanName, endpoint, objectMapper);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -61,8 +61,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
* @author Dave Syer * @author Dave Syer
* @author Madhura Bhave * @author Madhura Bhave
*/ */
public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint> public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint> extends RequestMappingHandlerMapping {
extends RequestMappingHandlerMapping {
private final Set<E> endpoints; private final Set<E> endpoints;
@ -92,8 +91,7 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
* @param corsConfiguration the CORS configuration for the endpoints * @param corsConfiguration the CORS configuration for the endpoints
* @since 1.3.0 * @since 1.3.0
*/ */
public AbstractEndpointHandlerMapping(Collection<? extends E> endpoints, public AbstractEndpointHandlerMapping(Collection<? extends E> endpoints, CorsConfiguration corsConfiguration) {
CorsConfiguration corsConfiguration) {
this.endpoints = new HashSet<E>(endpoints); this.endpoints = new HashSet<E>(endpoints);
postProcessEndpoints(this.endpoints); postProcessEndpoints(this.endpoints);
this.corsConfiguration = corsConfiguration; this.corsConfiguration = corsConfiguration;
@ -132,15 +130,13 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
@Override @Override
@Deprecated @Deprecated
protected void registerHandlerMethod(Object handler, Method method, protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
RequestMappingInfo mapping) {
if (mapping == null) { if (mapping == null) {
return; return;
} }
String[] patterns = getPatterns(handler, mapping); String[] patterns = getPatterns(handler, mapping);
if (!ObjectUtils.isEmpty(patterns)) { if (!ObjectUtils.isEmpty(patterns)) {
super.registerHandlerMethod(handler, method, super.registerHandlerMethod(handler, method, withNewPatterns(mapping, patterns));
withNewPatterns(mapping, patterns));
} }
} }
@ -163,8 +159,7 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
} }
private String[] getEndpointPatterns(String path, RequestMappingInfo mapping) { private String[] getEndpointPatterns(String path, RequestMappingInfo mapping) {
String patternPrefix = (StringUtils.hasText(this.prefix) ? this.prefix + path String patternPrefix = (StringUtils.hasText(this.prefix) ? this.prefix + path : path);
: path);
Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns(); Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
if (defaultPatterns.isEmpty()) { if (defaultPatterns.isEmpty()) {
return new String[] { patternPrefix, patternPrefix + ".json" }; return new String[] { patternPrefix, patternPrefix + ".json" };
@ -176,19 +171,16 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
return patterns.toArray(new String[patterns.size()]); return patterns.toArray(new String[patterns.size()]);
} }
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, String[] patternStrings) {
String[] patternStrings) { PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings, null, null,
PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings, useSuffixPatternMatch(), useTrailingSlashMatch(), null);
null, null, useSuffixPatternMatch(), useTrailingSlashMatch(), null); return new RequestMappingInfo(patterns, mapping.getMethodsCondition(), mapping.getParamsCondition(),
return new RequestMappingInfo(patterns, mapping.getMethodsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(),
mapping.getParamsCondition(), mapping.getHeadersCondition(),
mapping.getConsumesCondition(), mapping.getProducesCondition(),
mapping.getCustomCondition()); mapping.getCustomCondition());
} }
@Override @Override
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HttpServletRequest request) {
HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request); HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
if (this.securityInterceptor == null || CorsUtils.isCorsRequest(request)) { if (this.securityInterceptor == null || CorsUtils.isCorsRequest(request)) {
return chain; return chain;
@ -197,9 +189,8 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
} }
@Override @Override
protected HandlerExecutionChain getCorsHandlerExecutionChain( protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
HttpServletRequest request, HandlerExecutionChain chain, HandlerExecutionChain chain, CorsConfiguration config) {
CorsConfiguration config) {
chain = super.getCorsHandlerExecutionChain(request, chain, config); chain = super.getCorsHandlerExecutionChain(request, chain, config);
if (this.securityInterceptor == null) { if (this.securityInterceptor == null) {
return chain; return chain;
@ -235,8 +226,7 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
* @param prefix the prefix * @param prefix the prefix
*/ */
public void setPrefix(String prefix) { public void setPrefix(String prefix) {
Assert.isTrue("".equals(prefix) || StringUtils.startsWithIgnoreCase(prefix, "/"), Assert.isTrue("".equals(prefix) || StringUtils.startsWithIgnoreCase(prefix, "/"), "prefix must start with '/'");
"prefix must start with '/'");
this.prefix = prefix; this.prefix = prefix;
} }
@ -282,8 +272,7 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
} }
@Override @Override
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) {
RequestMappingInfo mappingInfo) {
return this.corsConfiguration; return this.corsConfiguration;
} }
@ -291,15 +280,13 @@ public abstract class AbstractEndpointHandlerMapping<E extends MvcEndpoint>
* {@link HandlerInterceptorAdapter} to ensure that * {@link HandlerInterceptorAdapter} to ensure that
* {@link PathExtensionContentNegotiationStrategy} is skipped for actuator endpoints. * {@link PathExtensionContentNegotiationStrategy} is skipped for actuator endpoints.
*/ */
private static final class SkipPathExtensionContentNegotiation private static final class SkipPathExtensionContentNegotiation extends HandlerInterceptorAdapter {
extends HandlerInterceptorAdapter {
private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";
.getName() + ".SKIP";
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
Object handler) throws Exception { throws Exception {
request.setAttribute(SKIP_ATTRIBUTE, Boolean.TRUE); request.setAttribute(SKIP_ATTRIBUTE, Boolean.TRUE);
return true; return true;
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,8 +29,7 @@ import org.springframework.util.Assert;
* @author Phillip Webb * @author Phillip Webb
* @since 1.3.0 * @since 1.3.0
*/ */
public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>> public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>> implements NamedMvcEndpoint {
implements NamedMvcEndpoint {
private final E delegate; private final E delegate;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,8 +31,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
* @author Lari Hotari * @author Lari Hotari
* @since 1.4.0 * @since 1.4.0
*/ */
public abstract class AbstractMvcEndpoint extends WebMvcConfigurerAdapter public abstract class AbstractMvcEndpoint extends WebMvcConfigurerAdapter implements MvcEndpoint, EnvironmentAware {
implements MvcEndpoint, EnvironmentAware {
private Environment environment; private Environment environment;
@ -80,8 +79,7 @@ public abstract class AbstractMvcEndpoint extends WebMvcConfigurerAdapter
public void setPath(String path) { public void setPath(String path) {
Assert.notNull(path, "Path must not be null"); Assert.notNull(path, "Path must not be null");
Assert.isTrue(path.isEmpty() || path.startsWith("/"), Assert.isTrue(path.isEmpty() || path.startsWith("/"), "Path must start with / or be empty");
"Path must start with / or be empty");
this.path = path; this.path = path;
} }
@ -95,8 +93,7 @@ public abstract class AbstractMvcEndpoint extends WebMvcConfigurerAdapter
@Override @Override
public boolean isSensitive() { public boolean isSensitive() {
return EndpointProperties.isSensitive(this.environment, this.sensitive, return EndpointProperties.isSensitive(this.environment, this.sensitive, this.sensitiveDefault);
this.sensitiveDefault);
} }
public void setSensitive(Boolean sensitive) { public void setSensitive(Boolean sensitive) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,8 +26,7 @@ import org.springframework.util.Assert;
* @author Madhura Bhave * @author Madhura Bhave
* @since 1.5.0 * @since 1.5.0
*/ */
public abstract class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint public abstract class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint implements NamedMvcEndpoint {
implements NamedMvcEndpoint {
private final String name; private final String name;
@ -37,8 +36,7 @@ public abstract class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint
this.name = name; this.name = name;
} }
public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive, public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive, boolean enabled) {
boolean enabled) {
super(path, sensitive, enabled); super(path, sensitive, enabled);
Assert.hasLength(name, "Name must not be empty"); Assert.hasLength(name, "Name must not be empty");
this.name = name; this.name = name;

@ -38,8 +38,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@RequestMapping(method = RequestMethod.GET, @RequestMapping(method = RequestMethod.GET,
produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
MediaType.APPLICATION_JSON_VALUE })
@interface ActuatorGetMapping { @interface ActuatorGetMapping {
/** /**

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,8 +34,7 @@ public final class ActuatorMediaTypes {
/** /**
* The {@code application/vnd.spring-boot.actuator.v1+json} media type. * The {@code application/vnd.spring-boot.actuator.v1+json} media type.
*/ */
public static final MediaType APPLICATION_ACTUATOR_V1_JSON = MediaType public static final MediaType APPLICATION_ACTUATOR_V1_JSON = MediaType.valueOf(APPLICATION_ACTUATOR_V1_JSON_VALUE);
.valueOf(APPLICATION_ACTUATOR_V1_JSON_VALUE);
private ActuatorMediaTypes() { private ActuatorMediaTypes() {

@ -40,10 +40,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@RequestMapping(method = RequestMethod.POST, @RequestMapping(method = RequestMethod.POST,
consumes = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, consumes = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE },
MediaType.APPLICATION_JSON_VALUE }, produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE })
@interface ActuatorPostMapping { @interface ActuatorPostMapping {
/** /**

@ -49,10 +49,8 @@ public class AuditEventsMvcEndpoint extends AbstractNamedMvcEndpoint {
@ActuatorGetMapping @ActuatorGetMapping
@ResponseBody @ResponseBody
public ResponseEntity<?> findByPrincipalAndAfterAndType( public ResponseEntity<?> findByPrincipalAndAfterAndType(@RequestParam(required = false) String principal,
@RequestParam(required = false) String principal, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after,
@RequestParam(required = false) @DateTimeFormat(
pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after,
@RequestParam(required = false) String type) { @RequestParam(required = false) String type) {
if (!isEnabled()) { if (!isEnabled()) {
return DISABLED_RESPONSE; return DISABLED_RESPONSE;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -47,20 +47,17 @@ public class DocsMvcEndpoint extends AbstractNamedMvcEndpoint {
@RequestMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
public String browse() { public String browse() {
return "forward:" + this.managementServletContext.getContextPath() + getPath() return "forward:" + this.managementServletContext.getContextPath() + getPath() + "/index.html";
+ "/index.html";
} }
@RequestMapping(value = "", produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(value = "", produces = MediaType.TEXT_HTML_VALUE)
public String redirect() { public String redirect() {
return "redirect:" + this.managementServletContext.getContextPath() + getPath() return "redirect:" + this.managementServletContext.getContextPath() + getPath() + "/";
+ "/";
} }
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler( registry.addResourceHandler(this.managementServletContext.getContextPath() + getPath() + "/**")
this.managementServletContext.getContextPath() + getPath() + "/**")
.addResourceLocations(DOCS_LOCATION); .addResourceLocations(DOCS_LOCATION);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -58,8 +58,7 @@ public class EndpointHandlerMapping extends AbstractEndpointHandlerMapping<MvcEn
* @param corsConfiguration the CORS configuration for the endpoints * @param corsConfiguration the CORS configuration for the endpoints
* @since 1.3.0 * @since 1.3.0
*/ */
public EndpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints, public EndpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints, CorsConfiguration corsConfiguration) {
CorsConfiguration corsConfiguration) {
super(endpoints, corsConfiguration); super(endpoints, corsConfiguration);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,8 +37,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@ConfigurationProperties(prefix = "endpoints.env") @ConfigurationProperties(prefix = "endpoints.env")
public class EnvironmentMvcEndpoint extends EndpointMvcAdapter public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements EnvironmentAware {
implements EnvironmentAware {
private Environment environment; private Environment environment;
@ -75,8 +74,7 @@ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter
@Override @Override
protected void getNames(Environment source, NameCallback callback) { protected void getNames(Environment source, NameCallback callback) {
if (source instanceof ConfigurableEnvironment) { if (source instanceof ConfigurableEnvironment) {
getNames(((ConfigurableEnvironment) source).getPropertySources(), getNames(((ConfigurableEnvironment) source).getPropertySources(), callback);
callback);
} }
} }
@ -110,8 +108,7 @@ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter
} }
private Object getValue(String name) { private Object getValue(String name) {
return ((EnvironmentEndpoint) getDelegate()).getResolver().getProperty(name, return ((EnvironmentEndpoint) getDelegate()).getResolver().getProperty(name, Object.class);
Object.class);
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,17 +45,13 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint implements ResourceLoaderAware {
implements ResourceLoaderAware {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private static HalBrowserLocation[] HAL_BROWSER_RESOURCE_LOCATIONS = { private static HalBrowserLocation[] HAL_BROWSER_RESOURCE_LOCATIONS = {
new HalBrowserLocation("classpath:/META-INF/spring-data-rest/hal-browser/", new HalBrowserLocation("classpath:/META-INF/spring-data-rest/hal-browser/", "index.html"),
"index.html"), new HalBrowserLocation("classpath:/META-INF/resources/webjars/hal-browser/9f96c74/", "browser.html") };
new HalBrowserLocation(
"classpath:/META-INF/resources/webjars/hal-browser/9f96c74/",
"browser.html") };
private HalBrowserLocation location; private HalBrowserLocation location;
@ -65,12 +61,10 @@ public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public String browse(HttpServletRequest request) { public String browse(HttpServletRequest request) {
ServletUriComponentsBuilder builder = ServletUriComponentsBuilder ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromRequest(request);
.fromRequest(request);
String uriString = builder.build().toUriString(); String uriString = builder.build().toUriString();
return "redirect:" + uriString + (uriString.endsWith("/") ? "" : "/") return "redirect:" + uriString + (uriString.endsWith("/") ? "" : "/") + this.location.getHtmlFile();
+ this.location.getHtmlFile();
} }
@Override @Override
@ -85,14 +79,12 @@ public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint
if (this.location != null) { if (this.location != null) {
String start = getManagementServletContext().getContextPath() + getPath(); String start = getManagementServletContext().getContextPath() + getPath();
registry.addResourceHandler(start + "/", start + "/**") registry.addResourceHandler(start + "/", start + "/**")
.addResourceLocations(this.location.getResourceLocation()) .addResourceLocations(this.location.getResourceLocation()).setCachePeriod(0).resourceChain(true)
.setCachePeriod(0).resourceChain(true)
.addTransformer(new InitialUrlTransformer()); .addTransformer(new InitialUrlTransformer());
} }
} }
public static HalBrowserLocation getHalBrowserLocation( public static HalBrowserLocation getHalBrowserLocation(ResourceLoader resourceLoader) {
ResourceLoader resourceLoader) {
for (HalBrowserLocation candidate : HAL_BROWSER_RESOURCE_LOCATIONS) { for (HalBrowserLocation candidate : HAL_BROWSER_RESOURCE_LOCATIONS) {
try { try {
Resource resource = resourceLoader.getResource(candidate.toString()); Resource resource = resourceLoader.getResource(candidate.toString());
@ -145,22 +137,19 @@ public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint
public Resource transform(HttpServletRequest request, Resource resource, public Resource transform(HttpServletRequest request, Resource resource,
ResourceTransformerChain transformerChain) throws IOException { ResourceTransformerChain transformerChain) throws IOException {
resource = transformerChain.transform(request, resource); resource = transformerChain.transform(request, resource);
if (resource.getFilename().equalsIgnoreCase( if (resource.getFilename().equalsIgnoreCase(HalBrowserMvcEndpoint.this.location.getHtmlFile())) {
HalBrowserMvcEndpoint.this.location.getHtmlFile())) {
return replaceInitialLink(request, resource); return replaceInitialLink(request, resource);
} }
return resource; return resource;
} }
private Resource replaceInitialLink(HttpServletRequest request, Resource resource) private Resource replaceInitialLink(HttpServletRequest request, Resource resource) throws IOException {
throws IOException {
byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
String content = new String(bytes, DEFAULT_CHARSET); String content = new String(bytes, DEFAULT_CHARSET);
List<String> pathSegments = new ArrayList<String>(ServletUriComponentsBuilder List<String> pathSegments = new ArrayList<String>(
.fromRequest(request).build().getPathSegments()); ServletUriComponentsBuilder.fromRequest(request).build().getPathSegments());
pathSegments.remove(pathSegments.size() - 1); pathSegments.remove(pathSegments.size() - 1);
String initial = "/" String initial = "/" + StringUtils.collectionToDelimitedString(pathSegments, "/");
+ StringUtils.collectionToDelimitedString(pathSegments, "/");
content = content.replace("entryPoint: '/'", "entryPoint: '" + initial + "'"); content = content.replace("entryPoint: '/'", "entryPoint: '" + initial + "'");
return new TransformedResource(resource, content.getBytes(DEFAULT_CHARSET)); return new TransformedResource(resource, content.getBytes(DEFAULT_CHARSET));
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,8 +39,7 @@ public class HalJsonMvcEndpoint extends AbstractNamedMvcEndpoint {
this.managementServletContext = managementServletContext; this.managementServletContext = managementServletContext;
} }
private static String getDefaultPath( private static String getDefaultPath(ManagementServletContext managementServletContext) {
ManagementServletContext managementServletContext) {
if (StringUtils.hasText(managementServletContext.getContextPath())) { if (StringUtils.hasText(managementServletContext.getContextPath())) {
return ""; return "";
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -54,8 +54,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties(prefix = "endpoints.health") @ConfigurationProperties(prefix = "endpoints.health")
public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint> public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint> implements EnvironmentAware {
implements EnvironmentAware {
private final boolean secure; private final boolean secure;
@ -75,8 +74,7 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
this(delegate, secure, null); this(delegate, secure, null);
} }
public HealthMvcEndpoint(HealthEndpoint delegate, boolean secure, public HealthMvcEndpoint(HealthEndpoint delegate, boolean secure, List<String> roles) {
List<String> roles) {
super(delegate); super(delegate);
this.secure = secure; this.secure = secure;
setupDefaultStatusMapping(); setupDefaultStatusMapping();
@ -90,8 +88,7 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
@Override @Override
public void setEnvironment(Environment environment) { public void setEnvironment(Environment environment) {
this.securityPropertyResolver = new RelaxedPropertyResolver(environment, this.securityPropertyResolver = new RelaxedPropertyResolver(environment, "management.security.");
"management.security.");
} }
/** /**
@ -182,8 +179,7 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
return cached.getHealth(); return cached.getHealth();
} }
protected boolean exposeHealthDetails(HttpServletRequest request, protected boolean exposeHealthDetails(HttpServletRequest request, Principal principal) {
Principal principal) {
if (!this.secure) { if (!this.secure) {
return true; return true;
} }
@ -209,15 +205,15 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
if (this.roles != null) { if (this.roles != null) {
return this.roles; return this.roles;
} }
String[] roles = StringUtils.commaDelimitedListToStringArray( String[] roles = StringUtils
this.securityPropertyResolver.getProperty("roles", "ROLE_ACTUATOR")); .commaDelimitedListToStringArray(this.securityPropertyResolver.getProperty("roles", "ROLE_ACTUATOR"));
roles = StringUtils.trimArrayElements(roles); roles = StringUtils.trimArrayElements(roles);
return Arrays.asList(roles); return Arrays.asList(roles);
} }
private boolean isSpringSecurityAuthentication(Principal principal) { private boolean isSpringSecurityAuthentication(Principal principal) {
return ClassUtils.isPresent("org.springframework.security.core.Authentication", return ClassUtils.isPresent("org.springframework.security.core.Authentication", null)
null) && principal instanceof Authentication; && principal instanceof Authentication;
} }
/** /**

@ -73,11 +73,9 @@ public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
this.timeout = timeout; this.timeout = timeout;
} }
@RequestMapping(method = RequestMethod.GET, @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public void invoke(@RequestParam(defaultValue = "true") boolean live, HttpServletRequest request,
public void invoke(@RequestParam(defaultValue = "true") boolean live, HttpServletResponse response) throws IOException, ServletException {
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if (!isEnabled()) { if (!isEnabled()) {
response.setStatus(HttpStatus.NOT_FOUND.value()); response.setStatus(HttpStatus.NOT_FOUND.value());
return; return;
@ -99,8 +97,7 @@ public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value()); response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
} }
private void dumpHeap(boolean live, HttpServletRequest request, private void dumpHeap(boolean live, HttpServletRequest request, HttpServletResponse response)
HttpServletResponse response)
throws IOException, ServletException, InterruptedException { throws IOException, ServletException, InterruptedException {
if (this.heapDumper == null) { if (this.heapDumper == null) {
this.heapDumper = createHeapDumper(); this.heapDumper = createHeapDumper();
@ -117,8 +114,7 @@ public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
private File createTempFile(boolean live) throws IOException { private File createTempFile(boolean live) throws IOException {
String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()); String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date());
File file = File.createTempFile("heapdump" + date + (live ? "-live" : ""), File file = File.createTempFile("heapdump" + date + (live ? "-live" : ""), ".hprof");
".hprof");
file.delete(); file.delete();
return file; return file;
} }
@ -141,11 +137,10 @@ public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
* @throws ServletException on servlet error * @throws ServletException on servlet error
* @throws IOException on IO error * @throws IOException on IO error
*/ */
protected void handle(File heapDumpFile, HttpServletRequest request, protected void handle(File heapDumpFile, HttpServletRequest request, HttpServletResponse response)
HttpServletResponse response) throws ServletException, IOException { throws ServletException, IOException {
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", response.setHeader("Content-Disposition", "attachment; filename=\"" + (heapDumpFile.getName() + ".gz") + "\"");
"attachment; filename=\"" + (heapDumpFile.getName() + ".gz") + "\"");
try { try {
InputStream in = new FileInputStream(heapDumpFile); InputStream in = new FileInputStream(heapDumpFile);
try { try {
@ -198,23 +193,21 @@ public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected HotSpotDiagnosticMXBeanHeapDumper() { protected HotSpotDiagnosticMXBeanHeapDumper() {
try { try {
Class<?> diagnosticMXBeanClass = ClassUtils.resolveClassName( Class<?> diagnosticMXBeanClass = ClassUtils
"com.sun.management.HotSpotDiagnosticMXBean", null); .resolveClassName("com.sun.management.HotSpotDiagnosticMXBean", null);
this.diagnosticMXBean = ManagementFactory.getPlatformMXBean( this.diagnosticMXBean = ManagementFactory
(Class<PlatformManagedObject>) diagnosticMXBeanClass); .getPlatformMXBean((Class<PlatformManagedObject>) diagnosticMXBeanClass);
this.dumpHeapMethod = ReflectionUtils.findMethod(diagnosticMXBeanClass, this.dumpHeapMethod = ReflectionUtils.findMethod(diagnosticMXBeanClass, "dumpHeap", String.class,
"dumpHeap", String.class, Boolean.TYPE); Boolean.TYPE);
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new HeapDumperUnavailableException( throw new HeapDumperUnavailableException("Unable to locate HotSpotDiagnosticMXBean", ex);
"Unable to locate HotSpotDiagnosticMXBean", ex);
} }
} }
@Override @Override
public void dumpHeap(File file, boolean live) { public void dumpHeap(File file, boolean live) {
ReflectionUtils.invokeMethod(this.dumpHeapMethod, this.diagnosticMXBean, ReflectionUtils.invokeMethod(this.dumpHeapMethod, this.diagnosticMXBean, file.getAbsolutePath(), live);
file.getAbsolutePath(), live);
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,8 +45,8 @@ import org.springframework.web.util.UrlPathHelper;
*/ */
@ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false) @ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false)
@HypermediaDisabled @HypermediaDisabled
public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint implements public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint
InitializingBean, ApplicationContextAware, ServletContextAware, DisposableBean { implements InitializingBean, ApplicationContextAware, ServletContextAware, DisposableBean {
private final ServletWrappingController controller = new ServletWrappingController(); private final ServletWrappingController controller = new ServletWrappingController();
@ -71,8 +71,7 @@ public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint implements
} }
@Override @Override
public final void setApplicationContext(ApplicationContext context) public final void setApplicationContext(ApplicationContext context) throws BeansException {
throws BeansException {
this.controller.setApplicationContext(context); this.controller.setApplicationContext(context);
} }
@ -82,10 +81,8 @@ public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint implements
} }
@RequestMapping("/**") @RequestMapping("/**")
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
throws Exception { return this.controller.handleRequest(new PathStripper(request, getPath()), response);
return this.controller.handleRequest(new PathStripper(request, getPath()),
response);
} }
private static class PathStripper extends HttpServletRequestWrapper { private static class PathStripper extends HttpServletRequestWrapper {
@ -102,8 +99,8 @@ public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint implements
@Override @Override
public String getPathInfo() { public String getPathInfo() {
String value = this.urlPathHelper.decodeRequestString( String value = this.urlPathHelper.decodeRequestString((HttpServletRequest) getRequest(),
(HttpServletRequest) getRequest(), super.getRequestURI()); super.getRequestURI());
if (value.contains(this.path)) { if (value.contains(this.path)) {
value = value.substring(value.indexOf(this.path) + this.path.length()); value = value.substring(value.indexOf(this.path) + this.path.length());
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -70,8 +70,7 @@ public class LogFileMvcEndpoint extends AbstractNamedMvcEndpoint {
} }
@RequestMapping(method = { RequestMethod.GET, RequestMethod.HEAD }) @RequestMapping(method = { RequestMethod.GET, RequestMethod.HEAD })
public void invoke(HttpServletRequest request, HttpServletResponse response) public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
throws ServletException, IOException {
if (!isEnabled()) { if (!isEnabled()) {
response.setStatus(HttpStatus.NOT_FOUND.value()); response.setStatus(HttpStatus.NOT_FOUND.value());
return; return;

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -64,8 +64,7 @@ public class LoggersMvcEndpoint extends EndpointMvcAdapter {
@ActuatorPostMapping("/{name:.*}") @ActuatorPostMapping("/{name:.*}")
@ResponseBody @ResponseBody
@HypermediaDisabled @HypermediaDisabled
public Object set(@PathVariable String name, public Object set(@PathVariable String name, @RequestBody Map<String, String> configuration) {
@RequestBody Map<String, String> configuration) {
if (!this.delegate.isEnabled()) { if (!this.delegate.isEnabled()) {
// Shouldn't happen - MVC endpoint shouldn't be registered when delegate's // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's
// disabled // disabled
@ -79,8 +78,7 @@ public class LoggersMvcEndpoint extends EndpointMvcAdapter {
private LogLevel getLogLevel(Map<String, String> configuration) { private LogLevel getLogLevel(Map<String, String> configuration) {
String level = configuration.get("configuredLevel"); String level = configuration.get("configuredLevel");
try { try {
return (level != null) ? LogLevel.valueOf(level.toUpperCase(Locale.ENGLISH)) return (level != null) ? LogLevel.valueOf(level.toUpperCase(Locale.ENGLISH)) : null;
: null;
} }
catch (IllegalArgumentException ex) { catch (IllegalArgumentException ex) {
throw new InvalidLogLevelException(level); throw new InvalidLogLevelException(level);

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -46,8 +46,7 @@ public class ManagementErrorEndpoint {
@RequestMapping("${server.error.path:${error.path:/error}}") @RequestMapping("${server.error.path:${error.path:/error}}")
@ResponseBody @ResponseBody
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
return this.errorAttributes.getErrorAttributes( return this.errorAttributes.getErrorAttributes(RequestContextHolder.currentRequestAttributes(), false);
RequestContextHolder.currentRequestAttributes(), false);
} }
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save