pull/13270/head
Phillip Webb 7 years ago
parent f84014d7df
commit 2dc4f1df00

@ -59,7 +59,8 @@ public class ServletEndpointManagementContextConfiguration {
private final ApplicationContext context; private final ApplicationContext context;
public WebMvcServletEndpointManagementContextConfiguration(ApplicationContext context) { public WebMvcServletEndpointManagementContextConfiguration(
ApplicationContext context) {
this.context = context; this.context = context;
} }
@ -67,8 +68,12 @@ public class ServletEndpointManagementContextConfiguration {
public ServletEndpointRegistrar servletEndpointRegistrar( public ServletEndpointRegistrar servletEndpointRegistrar(
WebEndpointProperties properties, WebEndpointProperties properties,
ServletEndpointsSupplier servletEndpointsSupplier) { ServletEndpointsSupplier servletEndpointsSupplier) {
DispatcherServletPathProvider servletPathProvider = this.context.getBean(DispatcherServletPathProvider.class); DispatcherServletPathProvider servletPathProvider = this.context
String servletPath = (servletPathProvider.getServletPath().equals("/") ? "" : servletPathProvider.getServletPath()); .getBean(DispatcherServletPathProvider.class);
String servletPath = servletPathProvider.getServletPath();
if (servletPath.equals("/")) {
servletPath = "";
}
return new ServletEndpointRegistrar(servletPath + properties.getBasePath(), return new ServletEndpointRegistrar(servletPath + properties.getBasePath(),
servletEndpointsSupplier.getEndpoints()); servletEndpointsSupplier.getEndpoints());
} }

@ -30,13 +30,12 @@ import org.springframework.util.StringUtils;
/** /**
* {@link BeanPostProcessor} that configures RabbitMQ metrics. Such arrangement is * {@link BeanPostProcessor} that configures RabbitMQ metrics. Such arrangement is
* necessary because a connection can be eagerly created and cached without a reference * necessary because a connection can be eagerly created and cached without a reference to
* to a proper {@link MetricsCollector}. * a proper {@link MetricsCollector}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
class RabbitConnectionFactoryMetricsPostProcessor class RabbitConnectionFactoryMetricsPostProcessor implements BeanPostProcessor, Ordered {
implements BeanPostProcessor, Ordered {
private static final String CONNECTION_FACTORY_SUFFIX = "connectionFactory"; private static final String CONNECTION_FACTORY_SUFFIX = "connectionFactory";

@ -219,7 +219,8 @@ public final class EndpointRequest {
} }
private String getEndpointId(Class<?> source) { private String getEndpointId(Class<?> source) {
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source, Endpoint.class); Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
Endpoint.class);
Assert.state(annotation != null, Assert.state(annotation != null,
() -> "Class " + source + " is not annotated with @Endpoint"); () -> "Class " + source + " is not annotated with @Endpoint");
return annotation.id(); return annotation.id();

@ -238,7 +238,8 @@ public final class EndpointRequest {
} }
private String getEndpointId(Class<?> source) { private String getEndpointId(Class<?> source) {
Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source, Endpoint.class); Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source,
Endpoint.class);
Assert.state(annotation != null, Assert.state(annotation != null,
() -> "Class " + source + " is not annotated with @Endpoint"); () -> "Class " + source + " is not annotated with @Endpoint");
return annotation.id(); return annotation.id();

@ -49,12 +49,11 @@ public class ServletEndpointManagementContextConfigurationTests {
@Test @Test
public void contextShouldContainServletEndpointRegistrar() { public void contextShouldContainServletEndpointRegistrar() {
FilteredClassLoader classLoader = new FilteredClassLoader( FilteredClassLoader classLoader = new FilteredClassLoader(ResourceConfig.class);
ResourceConfig.class);
this.contextRunner.withClassLoader(classLoader).run((context) -> { this.contextRunner.withClassLoader(classLoader).run((context) -> {
assertThat(context) assertThat(context).hasSingleBean(ServletEndpointRegistrar.class);
.hasSingleBean(ServletEndpointRegistrar.class); ServletEndpointRegistrar bean = context
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); .getBean(ServletEndpointRegistrar.class);
String basePath = (String) ReflectionTestUtils.getField(bean, "basePath"); String basePath = (String) ReflectionTestUtils.getField(bean, "basePath");
assertThat(basePath).isEqualTo("/test/actuator"); assertThat(basePath).isEqualTo("/test/actuator");
}); });
@ -65,9 +64,9 @@ public class ServletEndpointManagementContextConfigurationTests {
FilteredClassLoader classLoader = new FilteredClassLoader( FilteredClassLoader classLoader = new FilteredClassLoader(
DispatcherServlet.class); DispatcherServlet.class);
this.contextRunner.withClassLoader(classLoader).run((context) -> { this.contextRunner.withClassLoader(classLoader).run((context) -> {
assertThat(context) assertThat(context).hasSingleBean(ServletEndpointRegistrar.class);
.hasSingleBean(ServletEndpointRegistrar.class); ServletEndpointRegistrar bean = context
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); .getBean(ServletEndpointRegistrar.class);
String basePath = (String) ReflectionTestUtils.getField(bean, "basePath"); String basePath = (String) ReflectionTestUtils.getField(bean, "basePath");
assertThat(basePath).isEqualTo("/actuator"); assertThat(basePath).isEqualTo("/actuator");
}); });

@ -72,7 +72,6 @@ public class EndpointMBean implements DynamicMBean {
this.operations = getOperations(endpoint); this.operations = getOperations(endpoint);
} }
private Map<String, JmxOperation> getOperations(ExposableJmxEndpoint endpoint) { private Map<String, JmxOperation> getOperations(ExposableJmxEndpoint endpoint) {
Map<String, JmxOperation> operations = new HashMap<>(); Map<String, JmxOperation> operations = new HashMap<>();
endpoint.getOperations() endpoint.getOperations()
@ -94,7 +93,8 @@ public class EndpointMBean implements DynamicMBean {
+ "' has no operation named " + actionName; + "' has no operation named " + actionName;
throw new ReflectionException(new IllegalArgumentException(message), message); throw new ReflectionException(new IllegalArgumentException(message), message);
} }
ClassLoader previousClassLoader = overrideThreadContextClassLoader(this.classLoader); ClassLoader previousClassLoader = overrideThreadContextClassLoader(
this.classLoader);
try { try {
return invoke(operation, params); return invoke(operation, params);
} }

@ -33,8 +33,8 @@ public abstract class AbstractHealthAggregator implements HealthAggregator {
@Override @Override
public final Health aggregate(Map<String, Health> healths) { public final Health aggregate(Map<String, Health> healths) {
List<Status> statusCandidates = healths.values().stream() List<Status> statusCandidates = healths.values().stream().map(Health::getStatus)
.map(Health::getStatus).collect(Collectors.toList()); .collect(Collectors.toList());
Status status = aggregateStatus(statusCandidates); Status status = aggregateStatus(statusCandidates);
Map<String, Object> details = aggregateDetails(healths); Map<String, Object> details = aggregateDetails(healths);
return new Health.Builder(status, details).build(); return new Health.Builder(status, details).build();

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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.

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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,26 +64,28 @@ public class FreeMarkerAutoConfiguration {
@PostConstruct @PostConstruct
public void checkTemplateLocationExists() { public void checkTemplateLocationExists() {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled() && this.properties.isCheckTemplateLocation()) {
if (this.properties.isCheckTemplateLocation()) { List<TemplateLocation> locations = getLocations();
TemplateLocation templatePathLocation = null; if (locations.stream().noneMatch(this::locationExists)) {
List<TemplateLocation> locations = new ArrayList<>(); logger.warn("Cannot find template location(s): " + locations
for (String templateLoaderPath : this.properties.getTemplateLoaderPath()) { + " (please add some templates, "
TemplateLocation location = new TemplateLocation(templateLoaderPath); + "check your FreeMarker configuration, or set "
locations.add(location); + "spring.freemarker.checkTemplateLocation=false)");
if (location.exists(this.applicationContext)) {
templatePathLocation = location;
break;
}
}
if (templatePathLocation == null) {
logger.warn("Cannot find template location(s): " + locations
+ " (please add some templates, "
+ "check your FreeMarker configuration, or set "
+ "spring.freemarker.checkTemplateLocation=false)");
}
} }
} }
} }
private List<TemplateLocation> getLocations() {
List<TemplateLocation> locations = new ArrayList<>();
for (String templateLoaderPath : this.properties.getTemplateLoaderPath()) {
TemplateLocation location = new TemplateLocation(templateLoaderPath);
locations.add(location);
}
return locations;
}
private boolean locationExists(TemplateLocation location) {
return location.exists(this.applicationContext);
}
} }

@ -51,14 +51,13 @@ public class QuartzDataSourceInitializerTests {
@Test @Test
public void commentPrefixCanBeCustomized() { public void commentPrefixCanBeCustomized() {
this.contextRunner.withUserConfiguration(TestConfiguration.class) this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues( .withPropertyValues("spring.quartz.jdbc.comment-prefix=##",
"spring.quartz.jdbc.comment-prefix=##",
"spring.quartz.jdbc.schema=classpath:org/springframework/boot/autoconfigure/quartz/tables_@@platform@@.sql") "spring.quartz.jdbc.schema=classpath:org/springframework/boot/autoconfigure/quartz/tables_@@platform@@.sql")
.run((context) -> { .run((context) -> {
JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
assertThat(jdbcTemplate.queryForObject( assertThat(jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM QRTZ_TEST_TABLE", Integer.class)) "SELECT COUNT(*) FROM QRTZ_TEST_TABLE", Integer.class))
.isEqualTo(0); .isEqualTo(0);
}); });
} }
@ -69,7 +68,8 @@ public class QuartzDataSourceInitializerTests {
@Bean @Bean
public QuartzDataSourceInitializer initializer(DataSource dataSource, public QuartzDataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader, QuartzProperties properties) { ResourceLoader resourceLoader, QuartzProperties properties) {
return new QuartzDataSourceInitializer(dataSource, resourceLoader, properties); return new QuartzDataSourceInitializer(dataSource, resourceLoader,
properties);
} }
} }

@ -107,8 +107,8 @@ public class LocalHostUriTemplateHandlerTests {
URI uri = URI.create("http://www.example.com"); URI uri = URI.create("http://www.example.com");
given(uriTemplateHandler.expand("https://localhost:8080/", uriVariables)) given(uriTemplateHandler.expand("https://localhost:8080/", uriVariables))
.willReturn(uri); .willReturn(uri);
LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler( LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(environment,
environment, "https", uriTemplateHandler); "https", uriTemplateHandler);
assertThat(handler.expand("/", uriVariables)).isEqualTo(uri); assertThat(handler.expand("/", uriVariables)).isEqualTo(uri);
verify(uriTemplateHandler).expand("https://localhost:8080/", uriVariables); verify(uriTemplateHandler).expand("https://localhost:8080/", uriVariables);
} }

@ -18,7 +18,6 @@ package org.springframework.boot.context.properties.bind;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -83,24 +82,26 @@ abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
ResolvableType aggregateType, ResolvableType elementType) { ResolvableType aggregateType, ResolvableType elementType) {
ConfigurationProperty property = source.getConfigurationProperty(root); ConfigurationProperty property = source.getConfigurationProperty(root);
if (property != null) { if (property != null) {
Collection<Object> elements; bindValue(target, collection.get(), aggregateType, elementType,
Object value = property.getValue(); property.getValue());
if (value instanceof String && !StringUtils.hasText((String) value)) {
elements = Collections.emptyList();
}
else {
Object aggregate = convert(value, aggregateType, target.getAnnotations());
ResolvableType collectionType = ResolvableType
.forClassWithGenerics(collection.get().getClass(), elementType);
elements = convert(aggregate, collectionType);
}
collection.get().addAll(elements);
} }
else { else {
bindIndexed(source, root, elementBinder, collection, elementType); bindIndexed(source, root, elementBinder, collection, elementType);
} }
} }
private void bindValue(Bindable<?> target, Collection<Object> collection,
ResolvableType aggregateType, ResolvableType elementType, Object value) {
if (value instanceof String && !StringUtils.hasText((String) value)) {
return;
}
Object aggregate = convert(value, aggregateType, target.getAnnotations());
ResolvableType collectionType = ResolvableType
.forClassWithGenerics(collection.getClass(), elementType);
Collection<Object> elements = convert(aggregate, collectionType);
collection.addAll(elements);
}
private void bindIndexed(ConfigurationPropertySource source, private void bindIndexed(ConfigurationPropertySource source,
ConfigurationPropertyName root, AggregateElementBinder elementBinder, ConfigurationPropertyName root, AggregateElementBinder elementBinder,
IndexedCollectionSupplier collection, ResolvableType elementType) { IndexedCollectionSupplier collection, ResolvableType elementType) {

@ -79,8 +79,10 @@ public class ServletContextInitializerBeans
this.initializers = new LinkedMultiValueMap<>(); this.initializers = new LinkedMultiValueMap<>();
addServletContextInitializerBeans(beanFactory); addServletContextInitializerBeans(beanFactory);
addAdaptableBeans(beanFactory); addAdaptableBeans(beanFactory);
List<ServletContextInitializer> sortedInitializers = this.initializers.values().stream() List<ServletContextInitializer> sortedInitializers = this.initializers.values()
.flatMap(value -> value.stream().sorted(AnnotationAwareOrderComparator.INSTANCE)) .stream()
.flatMap(value -> value.stream()
.sorted(AnnotationAwareOrderComparator.INSTANCE))
.collect(Collectors.toList()); .collect(Collectors.toList());
this.sortedList = Collections.unmodifiableList(sortedInitializers); this.sortedList = Collections.unmodifiableList(sortedInitializers);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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.

Loading…
Cancel
Save