Polish
This commit is contained in:
@@ -22,6 +22,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingCon
|
||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -82,7 +83,7 @@ public class CloudFoundryActuatorAutoConfiguration {
|
||||
RestTemplateBuilder builder) {
|
||||
WebAnnotationEndpointDiscoverer endpointDiscoverer = new WebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext, parameterMapper, cachingConfigurationFactory,
|
||||
endpointMediaTypes, (id) -> id);
|
||||
endpointMediaTypes, EndpointPathResolver.useEndpointId());
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(
|
||||
new EndpointMapping("/cloudfoundryapplication"),
|
||||
endpointDiscoverer.discoverEndpoints(), endpointMediaTypes,
|
||||
@@ -142,7 +143,6 @@ public class CloudFoundryActuatorAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity builder) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* Default {@link EndpointPathResolver} implementation that use the
|
||||
* {@link Environment} to determine if an endpoint has a custom path.
|
||||
* Default {@link EndpointPathResolver} implementation that use the {@link Environment} to
|
||||
* determine if an endpoint has a custom path.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
|
||||
@@ -68,12 +68,11 @@ import org.springframework.integration.support.management.IntegrationManagementC
|
||||
@EnableConfigurationProperties(MetricsProperties.class)
|
||||
@Import({ MeterBindersConfiguration.class, WebMvcMetricsConfiguration.class,
|
||||
WebFluxMetricsConfiguration.class, RestTemplateMetricsConfiguration.class,
|
||||
DataSourcePoolMetricsConfiguration.class,
|
||||
AtlasExportConfiguration.class, DatadogExportConfiguration.class,
|
||||
GangliaExportConfiguration.class, GraphiteExportConfiguration.class,
|
||||
InfluxExportConfiguration.class, JmxExportConfiguration.class,
|
||||
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
|
||||
StatsdExportConfiguration.class })
|
||||
DataSourcePoolMetricsConfiguration.class, AtlasExportConfiguration.class,
|
||||
DatadogExportConfiguration.class, GangliaExportConfiguration.class,
|
||||
GraphiteExportConfiguration.class, InfluxExportConfiguration.class,
|
||||
JmxExportConfiguration.class, PrometheusExportConfiguration.class,
|
||||
SimpleExportConfiguration.class, StatsdExportConfiguration.class })
|
||||
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
|
||||
public class MetricsAutoConfiguration {
|
||||
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.jdbc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -62,12 +64,13 @@ public class DataSourcePoolMetricsConfiguration {
|
||||
|
||||
@Autowired
|
||||
public void bindDataSourcesToRegistry(Map<String, DataSource> dataSources) {
|
||||
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
|
||||
String beanName = entry.getKey();
|
||||
DataSource dataSource = entry.getValue();
|
||||
new DataSourcePoolMetrics(dataSource, this.metadataProviders, this.metricName,
|
||||
Tags.zip("name", getDataSourceName(beanName))).bindTo(this.registry);
|
||||
}
|
||||
dataSources.forEach(this::bindDataSourceToRegistry);
|
||||
}
|
||||
|
||||
private void bindDataSourceToRegistry(String beanName, DataSource dataSource) {
|
||||
List<Tag> tags = Tags.zip("name", getDataSourceName(beanName));
|
||||
new DataSourcePoolMetrics(dataSource, this.metadataProviders, this.metricName,
|
||||
tags).bindTo(this.registry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -220,8 +220,7 @@ public class CloudFoundryActuatorAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointPathCustomizationIsNotApplied()
|
||||
throws Exception {
|
||||
public void endpointPathCustomizationIsNotApplied() throws Exception {
|
||||
TestPropertyValues.of("endpoints.test.web.path=another/custom")
|
||||
.applyTo(this.context);
|
||||
this.context.register(TestConfiguration.class);
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
|
||||
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
@@ -219,7 +220,7 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
|
||||
DefaultConversionService.getSharedInstance());
|
||||
return new WebAnnotationEndpointDiscoverer(applicationContext,
|
||||
parameterMapper, (id) -> new CachingConfiguration(0),
|
||||
endpointMediaTypes, (id) -> id);
|
||||
endpointMediaTypes, EndpointPathResolver.useEndpointId());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -47,7 +47,8 @@ public class MetricsAutoConfigurationTests {
|
||||
@Test
|
||||
public void autoConfiguredDataSourceIsInstrumented() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.metrics.use-global-registry=false")
|
||||
.run((context) -> {
|
||||
@@ -61,7 +62,8 @@ public class MetricsAutoConfigurationTests {
|
||||
@Test
|
||||
public void autoConfiguredDataSourceWithCustomMetricName() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.metrics.jdbc.datasource-metric-name=custom.name",
|
||||
"spring.metrics.use-global-registry=false")
|
||||
@@ -76,7 +78,8 @@ public class MetricsAutoConfigurationTests {
|
||||
@Test
|
||||
public void dataSourceInstrumentationCanBeDisabled() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.metrics.jdbc.instrument-datasource=false",
|
||||
"spring.metrics.use-global-registry=false")
|
||||
@@ -90,15 +93,15 @@ public class MetricsAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void allDataSourcesCanBeInstrumented() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("metrics.use-global-registry=false")
|
||||
.run((context) -> {
|
||||
context.getBean("firstDataSource", DataSource.class)
|
||||
.getConnection().getMetaData();
|
||||
context.getBean("secondOne", DataSource.class)
|
||||
.getConnection().getMetaData();
|
||||
context.getBean("firstDataSource", DataSource.class).getConnection()
|
||||
.getMetaData();
|
||||
context.getBean("secondOne", DataSource.class).getConnection()
|
||||
.getMetaData();
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
assertThat(registry.find("data.source.max.connections")
|
||||
.tags("name", "first").meter()).isPresent();
|
||||
|
||||
@@ -18,8 +18,7 @@ package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
/**
|
||||
* A {@code ParameterMappingException} is thrown when a failure occurs during
|
||||
* {@link ParameterMapper#mapParameter(Object, Class) operation parameter
|
||||
* mapping}.
|
||||
* {@link ParameterMapper#mapParameter(Object, Class) operation parameter mapping}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
|
||||
@@ -23,15 +23,14 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
|
||||
/**
|
||||
* {@link ParameterMapper} that uses a {@link ConversionService} to map parameter
|
||||
* values if necessary.
|
||||
* {@link ParameterMapper} that uses a {@link ConversionService} to map parameter values
|
||||
* if necessary.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ConversionServiceParameterMapper
|
||||
implements ParameterMapper {
|
||||
public class ConversionServiceParameterMapper implements ParameterMapper {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
@@ -43,8 +42,7 @@ public class ConversionServiceParameterMapper
|
||||
* Create a new instance with the {@link ConversionService} to use.
|
||||
* @param conversionService the conversion service
|
||||
*/
|
||||
public ConversionServiceParameterMapper(
|
||||
ConversionService conversionService) {
|
||||
public ConversionServiceParameterMapper(ConversionService conversionService) {
|
||||
this.conversionService = new BinderConversionService(conversionService);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,8 +115,8 @@ public class JmxAnnotationEndpointDiscoverer
|
||||
public JmxEndpointOperation createOperation(String endpointId,
|
||||
AnnotationAttributes operationAttributes, Object target, Method method,
|
||||
OperationType type, long timeToLive) {
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(
|
||||
target, method, this.parameterMapper);
|
||||
ReflectiveOperationInvoker invoker = new ReflectiveOperationInvoker(target,
|
||||
method, this.parameterMapper);
|
||||
String operationName = method.getName();
|
||||
Class<?> outputType = getJmxType(method.getReturnType());
|
||||
String description = getDescription(method,
|
||||
|
||||
@@ -32,4 +32,12 @@ public interface EndpointPathResolver {
|
||||
*/
|
||||
String resolvePath(String endpointId);
|
||||
|
||||
/**
|
||||
* Returns an {@link EndpointPathResolver} that uses the endpoint ID as the path.
|
||||
* @return an {@link EndpointPathResolver} that uses the endpoint ID as the path
|
||||
*/
|
||||
static EndpointPathResolver useEndpointId() {
|
||||
return (endpointId) -> endpointId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.reactivestreams.Publisher;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointExposure;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.actuate.endpoint.OperationInvoker;
|
||||
import org.springframework.boot.actuate.endpoint.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||
import org.springframework.boot.actuate.endpoint.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
@@ -67,8 +67,8 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
* {@link Endpoint endpoints} and {@link WebEndpointExtension web extensions} using
|
||||
* the given {@link ApplicationContext}.
|
||||
* @param applicationContext the application context
|
||||
* @param parameterMapper the {@link ParameterMapper} used to
|
||||
* convert arguments when an operation is invoked
|
||||
* @param parameterMapper the {@link ParameterMapper} used to convert arguments when
|
||||
* an operation is invoked
|
||||
* @param cachingConfigurationFactory the {@link CachingConfiguration} factory to use
|
||||
* @param endpointMediaTypes the media types produced and consumed by web endpoint
|
||||
* operations
|
||||
@@ -81,8 +81,8 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointPathResolver endpointPathResolver) {
|
||||
super(applicationContext,
|
||||
new WebEndpointOperationFactory(parameterMapper,
|
||||
endpointMediaTypes, endpointPathResolver),
|
||||
new WebEndpointOperationFactory(parameterMapper, endpointMediaTypes,
|
||||
endpointPathResolver),
|
||||
WebEndpointOperation::getRequestPredicate, cachingConfigurationFactory);
|
||||
}
|
||||
|
||||
@@ -145,8 +145,8 @@ public class WebAnnotationEndpointDiscoverer extends
|
||||
determineConsumedMediaTypes(httpMethod, method),
|
||||
determineProducedMediaTypes(
|
||||
operationAttributes.getStringArray("produces"), method));
|
||||
OperationInvoker invoker = new ReflectiveOperationInvoker(
|
||||
target, method, this.parameterMapper);
|
||||
OperationInvoker invoker = new ReflectiveOperationInvoker(target, method,
|
||||
this.parameterMapper);
|
||||
if (timeToLive > 0) {
|
||||
invoker = new CachingOperationInvoker(invoker, timeToLive);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthI
|
||||
@Override
|
||||
public final Mono<Health> health() {
|
||||
try {
|
||||
return doHealthCheck(new Health.Builder())
|
||||
.onErrorResume(this::handleFailure);
|
||||
return doHealthCheck(new Health.Builder()).onErrorResume(this::handleFailure);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return handleFailure(ex);
|
||||
|
||||
@@ -385,7 +385,7 @@ public abstract class AbstractWebEndpointIntegrationTests<T extends Configurable
|
||||
DefaultConversionService.getSharedInstance());
|
||||
return new WebAnnotationEndpointDiscoverer(applicationContext,
|
||||
parameterMapper, (id) -> new CachingConfiguration(0),
|
||||
endpointMediaTypes(), (id) -> id);
|
||||
endpointMediaTypes(), EndpointPathResolver.useEndpointId());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -240,17 +240,18 @@ public class WebAnnotationEndpointDiscovererTests {
|
||||
@Test
|
||||
public void endpointPathCanBeCustomized() {
|
||||
load((id) -> null, (id) -> "custom/" + id,
|
||||
AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
||||
Map<String, EndpointInfo<WebEndpointOperation>> endpoints = mapEndpoints(
|
||||
discoverer.discoverEndpoints());
|
||||
assertThat(endpoints).containsOnlyKeys("test");
|
||||
EndpointInfo<WebEndpointOperation> endpoint = endpoints.get("test");
|
||||
assertThat(requestPredicates(endpoint)).has(requestPredicates(
|
||||
path("custom/test").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
||||
.produces("application/json"),
|
||||
path("custom/test/{id}").httpMethod(WebEndpointHttpMethod.GET).consumes()
|
||||
.produces("application/json")));
|
||||
});
|
||||
AdditionalOperationWebEndpointConfiguration.class, (discoverer) -> {
|
||||
Map<String, EndpointInfo<WebEndpointOperation>> endpoints = mapEndpoints(
|
||||
discoverer.discoverEndpoints());
|
||||
assertThat(endpoints).containsOnlyKeys("test");
|
||||
EndpointInfo<WebEndpointOperation> endpoint = endpoints.get("test");
|
||||
Condition<List<? extends OperationRequestPredicate>> expected = requestPredicates(
|
||||
path("custom/test").httpMethod(WebEndpointHttpMethod.GET)
|
||||
.consumes().produces("application/json"),
|
||||
path("custom/test/{id}").httpMethod(WebEndpointHttpMethod.GET)
|
||||
.consumes().produces("application/json"));
|
||||
assertThat(requestPredicates(endpoint)).has(expected);
|
||||
});
|
||||
}
|
||||
|
||||
private void load(Class<?> configuration,
|
||||
@@ -259,20 +260,18 @@ public class WebAnnotationEndpointDiscovererTests {
|
||||
}
|
||||
|
||||
private void load(CachingConfigurationFactory cachingConfigurationFactory,
|
||||
EndpointPathResolver endpointPathResolver,
|
||||
Class<?> configuration, Consumer<WebAnnotationEndpointDiscoverer> consumer) {
|
||||
EndpointPathResolver endpointPathResolver, Class<?> configuration,
|
||||
Consumer<WebAnnotationEndpointDiscoverer> consumer) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
configuration);
|
||||
try {
|
||||
consumer.accept(
|
||||
new WebAnnotationEndpointDiscoverer(context,
|
||||
new ConversionServiceParameterMapper(
|
||||
DefaultConversionService.getSharedInstance()),
|
||||
cachingConfigurationFactory,
|
||||
new EndpointMediaTypes(
|
||||
Collections.singletonList("application/json"),
|
||||
Collections.singletonList("application/json")),
|
||||
endpointPathResolver));
|
||||
consumer.accept(new WebAnnotationEndpointDiscoverer(context,
|
||||
new ConversionServiceParameterMapper(
|
||||
DefaultConversionService.getSharedInstance()),
|
||||
cachingConfigurationFactory,
|
||||
new EndpointMediaTypes(Collections.singletonList("application/json"),
|
||||
Collections.singletonList("application/json")),
|
||||
endpointPathResolver));
|
||||
}
|
||||
finally {
|
||||
context.close();
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.junit.runners.model.InitializationError;
|
||||
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
@@ -97,9 +98,9 @@ class JerseyEndpointsRunner extends AbstractWebEndpointRunner {
|
||||
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes,
|
||||
mediaTypes);
|
||||
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext,
|
||||
new ConversionServiceParameterMapper(), (id) -> null,
|
||||
endpointMediaTypes, (id) -> id);
|
||||
this.applicationContext, new ConversionServiceParameterMapper(),
|
||||
(id) -> null, endpointMediaTypes,
|
||||
EndpointPathResolver.useEndpointId());
|
||||
Collection<Resource> resources = new JerseyEndpointResourceFactory()
|
||||
.createEndpointResources(new EndpointMapping("/application"),
|
||||
discoverer.discoverEndpoints(), endpointMediaTypes);
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.runners.model.InitializationError;
|
||||
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
@@ -103,9 +104,9 @@ class WebFluxEndpointsRunner extends AbstractWebEndpointRunner {
|
||||
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes,
|
||||
mediaTypes);
|
||||
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext,
|
||||
new ConversionServiceParameterMapper(), (id) -> null,
|
||||
endpointMediaTypes, (id) -> id);
|
||||
this.applicationContext, new ConversionServiceParameterMapper(),
|
||||
(id) -> null, endpointMediaTypes,
|
||||
EndpointPathResolver.useEndpointId());
|
||||
return new WebFluxEndpointHandlerMapping(new EndpointMapping("/application"),
|
||||
discoverer.discoverEndpoints(), endpointMediaTypes,
|
||||
new CorsConfiguration());
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.runners.model.InitializationError;
|
||||
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
@@ -86,9 +87,9 @@ class WebMvcEndpointRunner extends AbstractWebEndpointRunner {
|
||||
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes,
|
||||
mediaTypes);
|
||||
WebAnnotationEndpointDiscoverer discoverer = new WebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext,
|
||||
new ConversionServiceParameterMapper(), (id) -> null,
|
||||
endpointMediaTypes, (id) -> id);
|
||||
this.applicationContext, new ConversionServiceParameterMapper(),
|
||||
(id) -> null, endpointMediaTypes,
|
||||
EndpointPathResolver.useEndpointId());
|
||||
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/application"),
|
||||
discoverer.discoverEndpoints(), endpointMediaTypes,
|
||||
new CorsConfiguration());
|
||||
|
||||
@@ -80,7 +80,8 @@ public class BatchAutoConfiguration {
|
||||
@ConditionalOnBean(DataSource.class)
|
||||
public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource,
|
||||
ResourceLoader resourceLoader) {
|
||||
return new BatchDataSourceInitializer(dataSource, resourceLoader, this.properties);
|
||||
return new BatchDataSourceInitializer(dataSource, resourceLoader,
|
||||
this.properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -141,8 +141,8 @@ public class JobLauncherCommandLineRunner
|
||||
throws JobExecutionAlreadyRunningException, JobRestartException,
|
||||
JobInstanceAlreadyCompleteException, JobParametersInvalidException,
|
||||
JobParametersNotFoundException {
|
||||
JobParameters nextParameters = new JobParametersBuilder(jobParameters, this.jobExplorer)
|
||||
.getNextJobParameters(job).toJobParameters();
|
||||
JobParameters nextParameters = new JobParametersBuilder(jobParameters,
|
||||
this.jobExplorer).getNextJobParameters(job).toJobParameters();
|
||||
JobExecution execution = this.jobLauncher.run(job, nextParameters);
|
||||
if (this.publisher != null) {
|
||||
this.publisher.publishEvent(new JobExecutionEvent(execution));
|
||||
|
||||
@@ -129,8 +129,7 @@ class DataSourceInitializer {
|
||||
if (mode == DataSourceInitializationMode.NEVER) {
|
||||
return false;
|
||||
}
|
||||
if (mode == DataSourceInitializationMode.EMBEDDED
|
||||
&& !isEmbedded()) {
|
||||
if (mode == DataSourceInitializationMode.EMBEDDED && !isEmbedded()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -153,7 +153,8 @@ public class QuartzAutoConfiguration {
|
||||
public QuartzDataSourceInitializer quartzDataSourceInitializer(
|
||||
DataSource dataSource, ResourceLoader resourceLoader,
|
||||
QuartzProperties properties) {
|
||||
return new QuartzDataSourceInitializer(dataSource, resourceLoader, properties);
|
||||
return new QuartzDataSourceInitializer(dataSource, resourceLoader,
|
||||
properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -33,8 +33,8 @@ public class QuartzDataSourceInitializer extends AbstractDataSourceInitializer {
|
||||
|
||||
private final QuartzProperties properties;
|
||||
|
||||
public QuartzDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
QuartzProperties properties) {
|
||||
public QuartzDataSourceInitializer(DataSource dataSource,
|
||||
ResourceLoader resourceLoader, QuartzProperties properties) {
|
||||
super(dataSource, resourceLoader);
|
||||
Assert.notNull(properties, "QuartzProperties must not be null");
|
||||
this.properties = properties;
|
||||
|
||||
@@ -40,7 +40,8 @@ class OAuth2WebSecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OAuth2AuthorizedClientService authorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
|
||||
public OAuth2AuthorizedClientService authorizedClientService(
|
||||
ClientRegistrationRepository clientRegistrationRepository) {
|
||||
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,16 @@ class ReactiveAuthenticationManagerConfiguration {
|
||||
ObjectProvider<PasswordEncoder> passwordEncoder) {
|
||||
String password = UUID.randomUUID().toString();
|
||||
logger.info(String.format("%n%nUsing default security password: %s%n", password));
|
||||
UserDetails userDetails = getUserDetails(password, passwordEncoder);
|
||||
return new MapReactiveUserDetailsService(userDetails);
|
||||
}
|
||||
|
||||
private UserDetails getUserDetails(String password,
|
||||
ObjectProvider<PasswordEncoder> passwordEncoder) {
|
||||
String encodedPassword = passwordEncoder
|
||||
.getIfAvailable(PasswordEncoderFactories::createDelegatingPasswordEncoder)
|
||||
.encode(password);
|
||||
UserDetails user = User.withUsername("user").password(encodedPassword).roles()
|
||||
.build();
|
||||
return new MapReactiveUserDetailsService(user);
|
||||
return User.withUsername("user").password(encodedPassword).roles().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ class JdbcSessionConfiguration {
|
||||
public JdbcSessionDataSourceInitializer jdbcSessionDataSourceInitializer(
|
||||
DataSource dataSource, ResourceLoader resourceLoader,
|
||||
JdbcSessionProperties properties) {
|
||||
return new JdbcSessionDataSourceInitializer(dataSource, resourceLoader, properties);
|
||||
return new JdbcSessionDataSourceInitializer(dataSource, resourceLoader,
|
||||
properties);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -155,6 +155,7 @@ public abstract class AbstractErrorWebExceptionHandler
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -205,30 +206,34 @@ public abstract class AbstractErrorWebExceptionHandler
|
||||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
|
||||
|
||||
this.errorAttributes.storeErrorInformation(throwable, exchange);
|
||||
ServerRequest request = ServerRequest.create(exchange, this.messageReaders);
|
||||
return getRoutingFunction(this.errorAttributes).route(request)
|
||||
.switchIfEmpty(Mono.error(throwable))
|
||||
.flatMap((handler) -> handler.handle(request)).flatMap((response) -> {
|
||||
// force content-type since writeTo won't overwrite response header
|
||||
// values
|
||||
exchange.getResponse().getHeaders()
|
||||
.setContentType(response.headers().getContentType());
|
||||
return response.writeTo(exchange, new ServerResponse.Context() {
|
||||
.flatMap((handler) -> handler.handle(request))
|
||||
.flatMap((response) -> write(exchange, response));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpMessageWriter<?>> messageWriters() {
|
||||
return AbstractErrorWebExceptionHandler.this.messageWriters;
|
||||
}
|
||||
private Mono<? extends Void> write(ServerWebExchange exchange,
|
||||
ServerResponse response) {
|
||||
// force content-type since writeTo won't overwrite response header values
|
||||
exchange.getResponse().getHeaders()
|
||||
.setContentType(response.headers().getContentType());
|
||||
return response.writeTo(exchange, new ResponseContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewResolver> viewResolvers() {
|
||||
return AbstractErrorWebExceptionHandler.this.viewResolvers;
|
||||
}
|
||||
private class ResponseContext implements ServerResponse.Context {
|
||||
|
||||
@Override
|
||||
public List<HttpMessageWriter<?>> messageWriters() {
|
||||
return AbstractErrorWebExceptionHandler.this.messageWriters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewResolver> viewResolvers() {
|
||||
return AbstractErrorWebExceptionHandler.this.viewResolvers;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +124,6 @@ public class DefaultErrorAttributes implements ErrorAttributes {
|
||||
@Override
|
||||
public void storeErrorInformation(Throwable error, ServerWebExchange exchange) {
|
||||
exchange.getAttributes().putIfAbsent(ERROR_ATTRIBUTE, error);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,12 +40,10 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
/**
|
||||
* Basic global {@link org.springframework.web.server.WebExceptionHandler}, rendering
|
||||
* {@link ErrorAttributes}.
|
||||
*
|
||||
* <p>
|
||||
* More specific errors can be handled either using Spring WebFlux abstractions (e.g.
|
||||
* {@code @ExceptionHandler} with the annotation model) or by adding
|
||||
* {@link RouterFunction} to the chain.
|
||||
*
|
||||
* <p>
|
||||
* This implementation will render error as HTML views if the client explicitly supports
|
||||
* that media type. It attempts to resolve error views using well known conventions. Will
|
||||
@@ -61,10 +59,8 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
* <li>{@code '/<templates>/error/error'}</li>
|
||||
* <li>{@code '/<static>/error/error.html'}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* If none found, a default "Whitelabel Error" HTML view will be rendered.
|
||||
*
|
||||
* <p>
|
||||
* If the client doesn't support HTML, the error information will be rendered as a JSON
|
||||
* payload.
|
||||
@@ -87,7 +83,6 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
|
||||
|
||||
/**
|
||||
* Create a new {@code DefaultErrorWebExceptionHandler} instance.
|
||||
*
|
||||
* @param errorAttributes the error attributes
|
||||
* @param resourceProperties the resources configuration properties
|
||||
* @param errorProperties the error configuration properties
|
||||
@@ -103,7 +98,6 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
|
||||
@Override
|
||||
protected RouterFunction<ServerResponse> getRoutingFunction(
|
||||
ErrorAttributes errorAttributes) {
|
||||
|
||||
return RouterFunctions.route(acceptsTextHtml(), this::renderErrorView)
|
||||
.andRoute(RequestPredicates.all(), this::renderErrorResponse);
|
||||
}
|
||||
@@ -116,11 +110,9 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
|
||||
protected Mono<ServerResponse> renderErrorView(ServerRequest request) {
|
||||
boolean includeStackTrace = isIncludeStackTrace(request, MediaType.TEXT_HTML);
|
||||
Map<String, Object> error = getErrorAttributes(request, includeStackTrace);
|
||||
|
||||
HttpStatus errorStatus = getHttpStatus(error);
|
||||
ServerResponse.BodyBuilder response = ServerResponse.status(errorStatus)
|
||||
.contentType(MediaType.TEXT_HTML);
|
||||
|
||||
return Flux
|
||||
.just("error/" + errorStatus.toString(),
|
||||
"error/" + SERIES_VIEWS.get(errorStatus.series()), "error/error")
|
||||
|
||||
@@ -94,8 +94,7 @@ public class MixedNeo4jRepositoriesAutoConfigurationTests {
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment)
|
||||
.and("spring.datasource.initialization-mode=never")
|
||||
.applyTo(context);
|
||||
.and("spring.datasource.initialization-mode=never").applyTo(context);
|
||||
context.register(config);
|
||||
context.register(DataSourceAutoConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class,
|
||||
|
||||
@@ -111,8 +111,7 @@ public class DataSourceInitializerInvokerTests {
|
||||
@Test
|
||||
public void dataSourceInitializedWithMultipleScripts() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.datasource.initialization-mode:always",
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("schema.sql")
|
||||
+ "," + getRelativeLocationFor("another.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("data.sql"))
|
||||
@@ -130,12 +129,13 @@ public class DataSourceInitializerInvokerTests {
|
||||
|
||||
@Test
|
||||
public void dataSourceInitializedWithExplicitSqlScriptEncoding() {
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.sqlScriptEncoding:UTF-8",
|
||||
"spring.datasource.schema:"
|
||||
+ getRelativeLocationFor("encoding-schema.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"))
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.sqlScriptEncoding:UTF-8",
|
||||
"spring.datasource.schema:"
|
||||
+ getRelativeLocationFor("encoding-schema.sql"),
|
||||
"spring.datasource.data:"
|
||||
+ getRelativeLocationFor("encoding-data.sql"))
|
||||
.run((context) -> {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
@@ -266,8 +266,7 @@ public class DataSourceInitializerInvokerTests {
|
||||
@Test
|
||||
public void dataSourceInitializedWithInvalidDataResource() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.datasource.initialization-mode:always",
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:"
|
||||
+ getRelativeLocationFor("schema.sql"),
|
||||
"spring.datasource.data:classpath:does/not/exist.sql")
|
||||
|
||||
@@ -94,7 +94,6 @@ public class DataSourceInitializerTests {
|
||||
given(connection.getMetaData()).willReturn(metadata);
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
given(dataSource.getConnection()).willReturn(connection);
|
||||
|
||||
DataSourceInitializer initializer = new DataSourceInitializer(dataSource,
|
||||
new DataSourceProperties());
|
||||
assertThat(initializer.createSchema()).isFalse();
|
||||
|
||||
@@ -68,8 +68,8 @@ public class DataSourcePropertiesTests {
|
||||
@Test
|
||||
public void determineUrlWithNoEmbeddedSupport() throws Exception {
|
||||
DataSourceProperties properties = new DataSourceProperties();
|
||||
properties.setBeanClassLoader(new HidePackagesClassLoader("org.h2",
|
||||
"org.apache.derby", "org.hsqldb"));
|
||||
properties.setBeanClassLoader(
|
||||
new HidePackagesClassLoader("org.h2", "org.apache.derby", "org.hsqldb"));
|
||||
properties.afterPropertiesSet();
|
||||
this.thrown.expect(DataSourceProperties.DataSourceBeanCreationException.class);
|
||||
this.thrown.expectMessage("Cannot determine embedded database url");
|
||||
|
||||
@@ -121,14 +121,12 @@ public class JndiDataSourceAutoConfigurationTests {
|
||||
throws IllegalStateException, NamingException {
|
||||
DataSource dataSource = new BasicDataSource();
|
||||
configureJndi("foo", dataSource);
|
||||
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.datasource.jndi-name:foo").applyTo(this.context);
|
||||
this.context.register(JndiDataSourceAutoConfiguration.class,
|
||||
MBeanExporterConfiguration.class,
|
||||
AnotherMBeanExporterConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
assertThat(this.context.getBean(DataSource.class)).isEqualTo(dataSource);
|
||||
for (MBeanExporter exporter : this.context.getBeansOfType(MBeanExporter.class)
|
||||
.values()) {
|
||||
|
||||
@@ -328,15 +328,14 @@ public class KafkaAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testConcurrentKafkaListenerContainerFactoryWithKafkaTemplate() {
|
||||
this.contextRunner
|
||||
.run((context) -> {
|
||||
ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory = context
|
||||
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(
|
||||
kafkaListenerContainerFactory);
|
||||
assertThat(dfa.getPropertyValue("replyTemplate"))
|
||||
.isSameAs(context.getBean(KafkaTemplate.class));
|
||||
});
|
||||
this.contextRunner.run((context) -> {
|
||||
ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory = context
|
||||
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(
|
||||
kafkaListenerContainerFactory);
|
||||
assertThat(dfa.getPropertyValue("replyTemplate"))
|
||||
.isSameAs(context.getBean(KafkaTemplate.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -208,8 +208,10 @@ public class SecurityAutoConfigurationTests {
|
||||
public void testJpaCoexistsHappily() throws Exception {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
TestPropertyValues.of("spring.datasource.url:jdbc:hsqldb:mem:testsecdb",
|
||||
"spring.datasource.initialization-mode:never").applyTo(this.context);
|
||||
TestPropertyValues
|
||||
.of("spring.datasource.url:jdbc:hsqldb:mem:testsecdb",
|
||||
"spring.datasource.initialization-mode:never")
|
||||
.applyTo(this.context);
|
||||
this.context.register(EntityConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
|
||||
@@ -92,11 +92,10 @@ public class OAuth2WebSecurityConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void configurationRegistersAuthorizedClientServiceBean() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(ClientRepositoryConfiguration.class,
|
||||
OAuth2WebSecurityConfiguration.class)
|
||||
.run(context -> {
|
||||
OAuth2AuthorizedClientService bean = context.getBean(OAuth2AuthorizedClientService.class);
|
||||
this.contextRunner.withUserConfiguration(ClientRepositoryConfiguration.class,
|
||||
OAuth2WebSecurityConfiguration.class).run(context -> {
|
||||
OAuth2AuthorizedClientService bean = context
|
||||
.getBean(OAuth2AuthorizedClientService.class);
|
||||
OAuth2AuthorizedClientService authorizedClientService = (OAuth2AuthorizedClientService) ReflectionTestUtils
|
||||
.getField(getAuthCodeFilters(context).get(0),
|
||||
"authorizedClientService");
|
||||
@@ -110,7 +109,8 @@ public class OAuth2WebSecurityConfigurationTests {
|
||||
.withUserConfiguration(OAuth2AuthorizedClientServiceConfiguration.class,
|
||||
OAuth2WebSecurityConfiguration.class)
|
||||
.run(context -> {
|
||||
OAuth2AuthorizedClientService bean = context.getBean(OAuth2AuthorizedClientService.class);
|
||||
OAuth2AuthorizedClientService bean = context
|
||||
.getBean(OAuth2AuthorizedClientService.class);
|
||||
OAuth2AuthorizedClientService authorizedClientService = (OAuth2AuthorizedClientService) ReflectionTestUtils
|
||||
.getField(getAuthCodeFilters(context).get(0),
|
||||
"authorizedClientService");
|
||||
@@ -211,8 +211,10 @@ public class OAuth2WebSecurityConfigurationTests {
|
||||
static class OAuth2AuthorizedClientServiceConfiguration {
|
||||
|
||||
@Bean
|
||||
public OAuth2AuthorizedClientService testAuthorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
|
||||
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
|
||||
public OAuth2AuthorizedClientService testAuthorizedClientService(
|
||||
ClientRegistrationRepository clientRegistrationRepository) {
|
||||
return new InMemoryOAuth2AuthorizedClientService(
|
||||
clientRegistrationRepository);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,8 +56,7 @@ public class ReactiveSecurityAutoConfigurationTests {
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
assertThat(context).getBean(WebFilterChainProxy.class)
|
||||
.isNotNull();
|
||||
assertThat(context).getBean(WebFilterChainProxy.class).isNotNull();
|
||||
assertThat(context).getBean(WebFluxSecurityConfiguration.class)
|
||||
.isNotNull();
|
||||
assertThat(context).getBean(WebFilterChainProxy.class).isNotNull();
|
||||
|
||||
@@ -159,11 +159,9 @@ public class DefaultErrorAttributesTests {
|
||||
Collections.singletonMap("a", "b"), "objectName");
|
||||
bindingResult.addError(new ObjectError("c", "d"));
|
||||
Exception ex = new WebExchangeBindException(stringParam, bindingResult);
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
|
||||
Map<String, Object> attributes = this.errorAttributes
|
||||
.getErrorAttributes(buildServerRequest(request, ex), false);
|
||||
|
||||
assertThat(attributes.get("message")).asString()
|
||||
.startsWith("Validation failed for argument at index 0 in method: "
|
||||
+ "public int org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorAttributesTests"
|
||||
|
||||
@@ -71,12 +71,14 @@ public class WebTestClientSpringBootTestIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http)
|
||||
throws Exception {
|
||||
http.authorizeExchange().anyExchange().permitAll();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -708,8 +708,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
|
||||
private Metadata.MetadataItemCondition webPath(String endpointId) {
|
||||
return Metadata.withProperty("endpoints." + endpointId + ".web.path")
|
||||
.ofType(String.class).withDefaultValue(endpointId).withDescription(String
|
||||
.format("Path of the %s endpoint.", endpointId));
|
||||
.ofType(String.class).withDefaultValue(endpointId)
|
||||
.withDescription(String.format("Path of the %s endpoint.", endpointId));
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition cacheTtl(String endpointId) {
|
||||
|
||||
@@ -141,9 +141,8 @@ final class JavaPluginAction implements PluginApplicationAction {
|
||||
|
||||
private void configureAdditionalMetadataLocations(Project project) {
|
||||
project.afterEvaluate((evaluated) -> {
|
||||
evaluated.getTasks().withType(JavaCompile.class, (compile) -> {
|
||||
configureAdditionalMetadataLocations(project, compile);
|
||||
});
|
||||
evaluated.getTasks().withType(JavaCompile.class,
|
||||
(compile) -> configureAdditionalMetadataLocations(project, compile));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -118,20 +118,20 @@ public class ConfigurationPropertiesBindingPostProcessor
|
||||
+ "PropertySourcesPlaceholderConfigurer or Environment");
|
||||
}
|
||||
PropertySources appliedPropertySources = configurer.getAppliedPropertySources();
|
||||
return environmentPropertySources == null ? appliedPropertySources
|
||||
: new CompositePropertySources(
|
||||
new FilteredPropertySources(appliedPropertySources,
|
||||
PropertySourcesPlaceholderConfigurer.ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME),
|
||||
environmentPropertySources);
|
||||
if (environmentPropertySources == null) {
|
||||
return appliedPropertySources;
|
||||
}
|
||||
return new CompositePropertySources(
|
||||
new FilteredPropertySources(appliedPropertySources,
|
||||
PropertySourcesPlaceholderConfigurer.ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME),
|
||||
environmentPropertySources);
|
||||
}
|
||||
|
||||
private MutablePropertySources extractEnvironmentPropertySources() {
|
||||
MutablePropertySources environmentPropertySources = null;
|
||||
if (this.environment instanceof ConfigurableEnvironment) {
|
||||
environmentPropertySources = ((ConfigurableEnvironment) this.environment)
|
||||
.getPropertySources();
|
||||
return ((ConfigurableEnvironment) this.environment).getPropertySources();
|
||||
}
|
||||
return environmentPropertySources;
|
||||
return null;
|
||||
}
|
||||
|
||||
private PropertySourcesPlaceholderConfigurer getSinglePropertySourcesPlaceholderConfigurer() {
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
@@ -33,21 +32,15 @@ import org.springframework.core.env.PropertySources;
|
||||
*/
|
||||
final class FilteredPropertySources implements PropertySources {
|
||||
|
||||
private final Set<String> filtered;
|
||||
|
||||
private final PropertySources delegate;
|
||||
|
||||
private final Set<String> filtered;
|
||||
|
||||
FilteredPropertySources(PropertySources delegate, String... filtered) {
|
||||
this.delegate = delegate;
|
||||
this.filtered = new HashSet<>(Arrays.asList(filtered));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PropertySource<?>> iterator() {
|
||||
return StreamSupport.stream(this.delegate.spliterator(), false)
|
||||
.filter(this::included).collect(Collectors.toList()).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String name) {
|
||||
if (included(name)) {
|
||||
@@ -64,6 +57,12 @@ final class FilteredPropertySources implements PropertySources {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PropertySource<?>> iterator() {
|
||||
return StreamSupport.stream(this.delegate.spliterator(), false)
|
||||
.filter(this::included).iterator();
|
||||
}
|
||||
|
||||
private boolean included(PropertySource<?> propertySource) {
|
||||
return included(propertySource.getName());
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
import reactor.ipc.netty.http.server.HttpServerOptions.Builder;
|
||||
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
@@ -66,33 +67,30 @@ public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@link NettyServerCustomizer}s that should be applied to the Netty
|
||||
* server builder. Calling this method will replace any existing customizers.
|
||||
* Set {@link NettyServerCustomizer}s that should be applied to the Netty server
|
||||
* builder. Calling this method will replace any existing customizers.
|
||||
* @param nettyServerCustomizers the customizers to set
|
||||
*/
|
||||
public void setNettyServerCustomizers(
|
||||
Collection<? extends NettyServerCustomizer> nettyServerCustomizers) {
|
||||
Assert.notNull(nettyServerCustomizers,
|
||||
"NettyServerCustomizers must not be null");
|
||||
Assert.notNull(nettyServerCustomizers, "NettyServerCustomizers must not be null");
|
||||
this.nettyServerCustomizers = new ArrayList<>(nettyServerCustomizers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add {@link NettyServerCustomizer}s that should applied while building the server.
|
||||
* @param nettyServerCustomizer the customizers to add
|
||||
*/
|
||||
public void addContextCustomizers(
|
||||
NettyServerCustomizer... nettyServerCustomizer) {
|
||||
public void addContextCustomizers(NettyServerCustomizer... nettyServerCustomizer) {
|
||||
Assert.notNull(nettyServerCustomizer,
|
||||
"NettyWebServerCustomizer must not be null");
|
||||
this.nettyServerCustomizers.addAll(Arrays.asList(nettyServerCustomizer));
|
||||
}
|
||||
|
||||
private HttpServer createHttpServer() {
|
||||
return HttpServer.builder().options(options -> {
|
||||
return HttpServer.builder().options((options) -> {
|
||||
options.listenAddress(getListenAddress());
|
||||
this.nettyServerCustomizers.forEach(customizer -> customizer.customize(options));
|
||||
applyCustomizers(options);
|
||||
}).build();
|
||||
}
|
||||
|
||||
@@ -100,9 +98,12 @@ public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
||||
if (getAddress() != null) {
|
||||
return new InetSocketAddress(getAddress().getHostAddress(), getPort());
|
||||
}
|
||||
else {
|
||||
return new InetSocketAddress(getPort());
|
||||
}
|
||||
return new InetSocketAddress(getPort());
|
||||
}
|
||||
|
||||
private void applyCustomizers(Builder options) {
|
||||
this.nettyServerCustomizers
|
||||
.forEach((customizer) -> customizer.customize(options));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,4 +33,5 @@ public interface NettyServerCustomizer {
|
||||
* @param builder the server options builder to customize
|
||||
*/
|
||||
void customize(HttpServerOptions.Builder builder);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.springframework.context.ConfigurableApplicationContext
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* Top level function acting as a Kotlin shortcut allowing to write
|
||||
* `runApplication<FooApplication>(arg1, arg2)` instead of
|
||||
|
||||
@@ -66,7 +66,6 @@ public class NettyReactiveWebServerFactoryTests
|
||||
}
|
||||
factory.setNettyServerCustomizers(Arrays.asList(customizers[0], customizers[1]));
|
||||
this.webServer = factory.getWebServer(new EchoHandler());
|
||||
|
||||
InOrder ordered = inOrder((Object[]) customizers);
|
||||
for (NettyServerCustomizer customizer : customizers) {
|
||||
ordered.verify(customizer).customize(any(HttpServerOptions.Builder.class));
|
||||
|
||||
@@ -117,6 +117,7 @@ class SpringApplicationExtensionsTests {
|
||||
open fun webServer(): MockServletWebServerFactory {
|
||||
return MockServletWebServerFactory()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"management.server.port=0", "management.server.context-path=/management"})
|
||||
"management.server.port=0", "management.server.context-path=/management" })
|
||||
@DirtiesContext
|
||||
public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
|
||||
|
||||
@@ -59,17 +59,17 @@ public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
|
||||
|
||||
@Test
|
||||
public void testSecureActuator() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/management/application/health",
|
||||
String.class);
|
||||
ResponseEntity<String> entity = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.managementPort
|
||||
+ "/management/application/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsecureActuator() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/management/application/status",
|
||||
String.class);
|
||||
ResponseEntity<String> entity = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.managementPort
|
||||
+ "/management/application/status", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
@@ -77,9 +77,8 @@ public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testMissing() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin")
|
||||
.getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/management/application/missing",
|
||||
String.class);
|
||||
.getForEntity("http://localhost:" + this.managementPort
|
||||
+ "/management/application/missing", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
assertThat(entity.getBody()).contains("\"status\":404");
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ public class ManagementAddressActuatorApplicationTests {
|
||||
@Test
|
||||
public void testHealth() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate()
|
||||
.withBasicAuth("user", getPassword())
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/admin/application/health",
|
||||
.withBasicAuth("user", getPassword()).getForEntity("http://localhost:"
|
||||
+ this.managementPort + "/admin/application/health",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
|
||||
@@ -49,9 +49,9 @@ public class ServletPathSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testErrorPath() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.withBasicAuth("user", getPassword())
|
||||
.getForEntity("/spring/error",
|
||||
Map.class);
|
||||
ResponseEntity<Map> entity = this.restTemplate
|
||||
.withBasicAuth("user", getPassword())
|
||||
.getForEntity("/spring/error", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
|
||||
@@ -30,7 +30,7 @@ public class City implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="city_generator", sequenceName="city_sequence", initialValue = 23)
|
||||
@SequenceGenerator(name = "city_generator", sequenceName = "city_sequence", initialValue = 23)
|
||||
@GeneratedValue(generator = "city_generator")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class Hotel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="hotel_generator", sequenceName="hotel_sequence", initialValue = 28)
|
||||
@SequenceGenerator(name = "hotel_generator", sequenceName = "hotel_sequence", initialValue = 28)
|
||||
@GeneratedValue(generator = "hotel_generator")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Review implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="review_generator", sequenceName="review_sequence", initialValue = 64)
|
||||
@SequenceGenerator(name = "review_generator", sequenceName = "review_sequence", initialValue = 64)
|
||||
@GeneratedValue(generator = "review_generator")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class City implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="city_generator", sequenceName="city_sequence", initialValue = 23)
|
||||
@SequenceGenerator(name = "city_generator", sequenceName = "city_sequence", initialValue = 23)
|
||||
@GeneratedValue(generator = "city_generator")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class Hotel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="hotel_generator", sequenceName="hotel_sequence", initialValue = 28)
|
||||
@SequenceGenerator(name = "hotel_generator", sequenceName = "hotel_sequence", initialValue = 28)
|
||||
@GeneratedValue(generator = "hotel_generator")
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import javax.persistence.SequenceGenerator;
|
||||
@Entity
|
||||
public class Person {
|
||||
@Id
|
||||
@SequenceGenerator(name="person_generator", sequenceName="person_sequence", allocationSize = 1)
|
||||
@SequenceGenerator(name = "person_generator", sequenceName = "person_sequence", allocationSize = 1)
|
||||
@GeneratedValue(generator = "person_generator")
|
||||
private Long id;
|
||||
private String firstName;
|
||||
|
||||
@@ -28,7 +28,7 @@ import javax.persistence.SequenceGenerator;
|
||||
public class Note {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="note_generator", sequenceName="note_sequence", initialValue = 5)
|
||||
@SequenceGenerator(name = "note_generator", sequenceName = "note_sequence", initialValue = 5)
|
||||
@GeneratedValue(generator = "note_generator")
|
||||
private long id;
|
||||
|
||||
|
||||
@@ -57,10 +57,8 @@ public class SampleOAuth2ClientApplicationTests {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody())
|
||||
.contains("/oauth2/authorization/github-client-1");
|
||||
assertThat(entity.getBody())
|
||||
.contains("/oauth2/authorization/github-client-2");
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/github-client-1");
|
||||
assertThat(entity.getBody()).contains("/oauth2/authorization/github-client-2");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public class SamplePropertyValidationApplicationTests {
|
||||
@Test
|
||||
public void bindValidProperties() {
|
||||
this.context.register(SamplePropertyValidationApplication.class);
|
||||
TestPropertyValues.of("sample.host:192.168.0.1",
|
||||
"sample.port:9090").applyTo(this.context);
|
||||
TestPropertyValues.of("sample.host:192.168.0.1", "sample.port:9090")
|
||||
.applyTo(this.context);
|
||||
this.context.refresh();
|
||||
SampleProperties properties = this.context.getBean(SampleProperties.class);
|
||||
assertThat(properties.getHost()).isEqualTo("192.168.0.1");
|
||||
@@ -60,8 +60,8 @@ public class SamplePropertyValidationApplicationTests {
|
||||
@Test
|
||||
public void bindInvalidHost() {
|
||||
this.context.register(SamplePropertyValidationApplication.class);
|
||||
TestPropertyValues.of("sample.host:xxxxxx",
|
||||
"sample.port:9090").applyTo(this.context);
|
||||
TestPropertyValues.of("sample.host:xxxxxx", "sample.port:9090")
|
||||
.applyTo(this.context);
|
||||
this.thrown.expect(BeanCreationException.class);
|
||||
this.thrown.expectMessage("Failed to bind properties under 'sample'");
|
||||
this.context.refresh();
|
||||
@@ -79,8 +79,8 @@ public class SamplePropertyValidationApplicationTests {
|
||||
public void validatorOnlyCalledOnSupportedClass() {
|
||||
this.context.register(SamplePropertyValidationApplication.class);
|
||||
this.context.register(ServerProperties.class); // our validator will not apply
|
||||
TestPropertyValues.of("sample.host:192.168.0.1",
|
||||
"sample.port:9090").applyTo(this.context);
|
||||
TestPropertyValues.of("sample.host:192.168.0.1", "sample.port:9090")
|
||||
.applyTo(this.context);
|
||||
this.context.refresh();
|
||||
SampleProperties properties = this.context.getBean(SampleProperties.class);
|
||||
assertThat(properties.getHost()).isEqualTo("192.168.0.1");
|
||||
|
||||
Reference in New Issue
Block a user