Polish
This commit is contained in:
@@ -95,8 +95,7 @@ public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMappi
|
||||
ExposableControllerEndpoint endpoint, RequestMappingInfo mapping) {
|
||||
Set<PathPattern> patterns = mapping.getPatternsCondition().getPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
patterns = new HashSet<>(
|
||||
Arrays.asList(getPathPatternParser().parse("")));
|
||||
patterns = new HashSet<>(Arrays.asList(getPathPatternParser().parse("")));
|
||||
}
|
||||
PathPattern[] endpointMappedPatterns = patterns.stream()
|
||||
.map((pattern) -> getEndpointMappedPattern(endpoint, pattern))
|
||||
|
||||
@@ -64,8 +64,8 @@ class DataSourceJmxConfiguration {
|
||||
public void validateMBeans() {
|
||||
HikariDataSource hikariDataSource = unwrapHikariDataSource();
|
||||
if (hikariDataSource != null && hikariDataSource.isRegisterMbeans()) {
|
||||
this.mBeanExporter.ifUnique((exporter) ->
|
||||
exporter.addExcludedBean("dataSource"));
|
||||
this.mBeanExporter
|
||||
.ifUnique((exporter) -> exporter.addExcludedBean("dataSource"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,12 +218,10 @@ public class EmbeddedLdapAutoConfiguration {
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
Builder message = ConditionMessage.forCondition("Embedded LDAP");
|
||||
Environment environment = context.getEnvironment();
|
||||
if (environment != null
|
||||
&& !Binder.get(environment)
|
||||
.bind("spring.ldap.embedded.base-dn", STRING_LIST)
|
||||
.orElseGet(Collections::emptyList).isEmpty()) {
|
||||
return ConditionOutcome
|
||||
.match(message.because("Found base-dn property"));
|
||||
if (environment != null && !Binder.get(environment)
|
||||
.bind("spring.ldap.embedded.base-dn", STRING_LIST)
|
||||
.orElseGet(Collections::emptyList).isEmpty()) {
|
||||
return ConditionOutcome.match(message.because("Found base-dn property"));
|
||||
}
|
||||
return ConditionOutcome.noMatch(message.because("No base-dn property found"));
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ public class ConditionEvaluationReportLoggingListener
|
||||
}
|
||||
}
|
||||
else if (event instanceof ApplicationFailedEvent
|
||||
&& ((ApplicationFailedEvent) event)
|
||||
.getApplicationContext() == initializerApplicationContext) {
|
||||
&& ((ApplicationFailedEvent) event)
|
||||
.getApplicationContext() == initializerApplicationContext) {
|
||||
logAutoConfigurationReport(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,24 +49,26 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
public class DataSourceJmxConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.datasource.url="
|
||||
+ "jdbc:hsqldb:mem:test-" + UUID.randomUUID())
|
||||
.withPropertyValues("spring.datasource.url=" + "jdbc:hsqldb:mem:test-"
|
||||
+ UUID.randomUUID())
|
||||
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
|
||||
DataSourceAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void hikariAutoConfiguredCanUseRegisterMBeans() {
|
||||
String poolName = UUID.randomUUID().toString();
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.datasource.name=" + poolName,
|
||||
"spring.datasource.hikari.register-mbeans=true").run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
validateHikariMBeansRegistration(mBeanServer, poolName, true);
|
||||
});
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.datasource.name=" + poolName,
|
||||
"spring.datasource.hikari.register-mbeans=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
validateHikariMBeansRegistration(mBeanServer, poolName, true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -75,34 +77,39 @@ public class DataSourceJmxConfigurationTests {
|
||||
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
Set<ObjectInstance> existingInstances = mBeanServer
|
||||
.queryMBeans(new ObjectName("com.zaxxer.hikari:type=*"), null);
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.datasource.hikari.register-mbeans=true").run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
// We can't rely on the number of MBeans so we're checking that the pool and pool
|
||||
// config MBeans were registered
|
||||
assertThat(mBeanServer
|
||||
.queryMBeans(new ObjectName("com.zaxxer.hikari:type=*"), null).size())
|
||||
.isEqualTo(existingInstances.size() + 2);
|
||||
});
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.datasource.hikari.register-mbeans=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
// We can't rely on the number of MBeans so we're checking that the
|
||||
// pool and pool
|
||||
// config MBeans were registered
|
||||
assertThat(mBeanServer
|
||||
.queryMBeans(new ObjectName("com.zaxxer.hikari:type=*"), null)
|
||||
.size()).isEqualTo(existingInstances.size() + 2);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hikariAutoConfiguredUsesJmsFlag() {
|
||||
String poolName = UUID.randomUUID().toString();
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.jmx.enabled=false", "spring.datasource.name=" + poolName,
|
||||
"spring.datasource.hikari.register-mbeans=true").run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
// Hikari can still register mBeans
|
||||
validateHikariMBeansRegistration(ManagementFactory.getPlatformMBeanServer(),
|
||||
poolName, true);
|
||||
});
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.datasource.type=" + HikariDataSource.class.getName(),
|
||||
"spring.jmx.enabled=false", "spring.datasource.name=" + poolName,
|
||||
"spring.datasource.hikari.register-mbeans=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(HikariDataSource.class);
|
||||
assertThat(context.getBean(HikariDataSource.class).isRegisterMbeans())
|
||||
.isTrue();
|
||||
// Hikari can still register mBeans
|
||||
validateHikariMBeansRegistration(
|
||||
ManagementFactory.getPlatformMBeanServer(), poolName, true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -115,8 +122,9 @@ public class DataSourceJmxConfigurationTests {
|
||||
"spring.datasource.hikari.register-mbeans=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(javax.sql.DataSource.class);
|
||||
HikariDataSource hikariDataSource = context.getBean(
|
||||
javax.sql.DataSource.class).unwrap(HikariDataSource.class);
|
||||
HikariDataSource hikariDataSource = context
|
||||
.getBean(javax.sql.DataSource.class)
|
||||
.unwrap(HikariDataSource.class);
|
||||
assertThat(hikariDataSource.isRegisterMbeans()).isTrue();
|
||||
MBeanServer mBeanServer = context.getBean(MBeanServer.class);
|
||||
validateHikariMBeansRegistration(mBeanServer, poolName, true);
|
||||
@@ -127,18 +135,19 @@ public class DataSourceJmxConfigurationTests {
|
||||
String poolName, boolean expected) throws MalformedObjectNameException {
|
||||
assertThat(mBeanServer.isRegistered(
|
||||
new ObjectName("com.zaxxer.hikari:type=Pool (" + poolName + ")")))
|
||||
.isEqualTo(expected);
|
||||
.isEqualTo(expected);
|
||||
assertThat(mBeanServer.isRegistered(
|
||||
new ObjectName("com.zaxxer.hikari:type=PoolConfig (" + poolName + ")")))
|
||||
.isEqualTo(expected);
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tomcatDoesNotExposeMBeanPoolByDefault() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.datasource.type=" + DataSource.class.getName())
|
||||
.run((context) ->
|
||||
assertThat(context).doesNotHaveBean(ConnectionPool.class));
|
||||
.withPropertyValues(
|
||||
"spring.datasource.type=" + DataSource.class.getName())
|
||||
.run((context) -> assertThat(context)
|
||||
.doesNotHaveBean(ConnectionPool.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,10 +155,11 @@ public class DataSourceJmxConfigurationTests {
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.datasource.type=" + DataSource.class.getName(),
|
||||
"spring.datasource.jmx-enabled=true").run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionPool.class);
|
||||
assertThat(context.getBean(DataSourceProxy.class).createPool().getJmxPool())
|
||||
.isSameAs(context.getBean(ConnectionPool.class));
|
||||
});
|
||||
assertThat(context).hasSingleBean(ConnectionPool.class);
|
||||
assertThat(context.getBean(DataSourceProxy.class).createPool()
|
||||
.getJmxPool())
|
||||
.isSameAs(context.getBean(ConnectionPool.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -162,7 +172,6 @@ public class DataSourceJmxConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class DataSourceBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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");
|
||||
* 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");
|
||||
* 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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,8 +22,6 @@ import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.assertj.core.description.Description;
|
||||
import org.assertj.core.description.TextDescription;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
@@ -266,8 +266,7 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||
index = separator + SEPARATOR.length();
|
||||
}
|
||||
JarEntryName jarEntryName = JarEntryName.get(spec, index);
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get())
|
||||
&& !jarEntryName.isEmpty()
|
||||
if (Boolean.TRUE.equals(useFastExceptions.get()) && !jarEntryName.isEmpty()
|
||||
&& !jarFile.containsEntry(jarEntryName.toString())) {
|
||||
return NOT_FOUND_CONNECTION;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -142,8 +142,7 @@ public class ApplicationPidFileWriter
|
||||
writePidFile(event);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
String message = String.format("Cannot create pid file %s",
|
||||
this.file);
|
||||
String message = String.format("Cannot create pid file %s", this.file);
|
||||
if (failOnWriteError(event)) {
|
||||
throw new IllegalStateException(message, ex);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.boot.web.embedded.netty;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import reactor.ipc.netty.http.server.HttpServerOptions;
|
||||
import reactor.ipc.netty.http.server.HttpServerRequest;
|
||||
import reactor.ipc.netty.http.server.HttpServerResponse;
|
||||
@@ -26,11 +28,14 @@ import reactor.ipc.netty.http.server.HttpServerResponse;
|
||||
import org.springframework.boot.web.server.Compression;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Configure the HTTP compression on an Reactor Netty request/response handler.
|
||||
*
|
||||
* @author Stephane Maldini
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
final class CompressionCustomizer implements NettyServerCustomizer {
|
||||
|
||||
@@ -45,71 +50,46 @@ final class CompressionCustomizer implements NettyServerCustomizer {
|
||||
if (this.compression.getMinResponseSize() >= 0) {
|
||||
builder.compression(this.compression.getMinResponseSize());
|
||||
}
|
||||
BiPredicate<HttpServerRequest, HttpServerResponse> compressPredicate = null;
|
||||
if (this.compression.getMimeTypes() != null &&
|
||||
this.compression.getMimeTypes().length > 0) {
|
||||
compressPredicate = new CompressibleMimeTypePredicate(this.compression.getMimeTypes());
|
||||
}
|
||||
if (this.compression.getExcludedUserAgents() != null &&
|
||||
this.compression.getExcludedUserAgents().length > 0) {
|
||||
BiPredicate<HttpServerRequest, HttpServerResponse> agentCompressPredicate =
|
||||
new CompressibleAgentPredicate(this.compression.getExcludedUserAgents());
|
||||
compressPredicate = compressPredicate == null ?
|
||||
agentCompressPredicate :
|
||||
compressPredicate.and(agentCompressPredicate);
|
||||
}
|
||||
if (compressPredicate != null) {
|
||||
builder.compression(compressPredicate);
|
||||
}
|
||||
CompressionPredicate mimeTypes = getMimeTypesPredicate(
|
||||
this.compression.getMimeTypes());
|
||||
CompressionPredicate excludedUserAgents = getExcludedUserAgentsPredicate(
|
||||
this.compression.getExcludedUserAgents());
|
||||
builder.compression(mimeTypes.and(excludedUserAgents));
|
||||
}
|
||||
|
||||
private static class CompressibleAgentPredicate
|
||||
implements BiPredicate<HttpServerRequest, HttpServerResponse> {
|
||||
|
||||
private final String[] excludedAgents;
|
||||
|
||||
CompressibleAgentPredicate(String[] excludedAgents) {
|
||||
this.excludedAgents = new String[excludedAgents.length];
|
||||
System.arraycopy(excludedAgents, 0, this.excludedAgents, 0, excludedAgents.length);
|
||||
private CompressionPredicate getMimeTypesPredicate(String[] mimeTypes) {
|
||||
if (ObjectUtils.isEmpty(mimeTypes)) {
|
||||
return CompressionPredicate.ALWAYS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(HttpServerRequest request, HttpServerResponse response) {
|
||||
for (String excludedAgent : this.excludedAgents) {
|
||||
if (request.requestHeaders()
|
||||
.contains(HttpHeaderNames.USER_AGENT, excludedAgent, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CompressibleMimeTypePredicate
|
||||
implements BiPredicate<HttpServerRequest, HttpServerResponse> {
|
||||
|
||||
private final MimeType[] mimeTypes;
|
||||
|
||||
CompressibleMimeTypePredicate(String[] mimeTypes) {
|
||||
this.mimeTypes = new MimeType[mimeTypes.length];
|
||||
for (int i = 0; i < mimeTypes.length; i++) {
|
||||
this.mimeTypes[i] = MimeTypeUtils.parseMimeType(mimeTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(HttpServerRequest request, HttpServerResponse response) {
|
||||
return (request, response) -> {
|
||||
String contentType = response.responseHeaders()
|
||||
.get(HttpHeaderNames.CONTENT_TYPE);
|
||||
if (contentType != null) {
|
||||
for (MimeType mimeType : this.mimeTypes) {
|
||||
if (mimeType.isCompatibleWith(MimeTypeUtils.parseMimeType(contentType))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(contentType)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
MimeType contentMimeType = MimeTypeUtils.parseMimeType(contentType);
|
||||
return Arrays.stream(mimeTypes).map(MimeTypeUtils::parseMimeType)
|
||||
.anyMatch((candidate) -> candidate.isCompatibleWith(contentMimeType));
|
||||
};
|
||||
}
|
||||
|
||||
private CompressionPredicate getExcludedUserAgentsPredicate(
|
||||
String[] excludedUserAgents) {
|
||||
if (ObjectUtils.isEmpty(excludedUserAgents)) {
|
||||
return CompressionPredicate.ALWAYS;
|
||||
}
|
||||
return (request, response) -> {
|
||||
HttpHeaders headers = request.requestHeaders();
|
||||
return Arrays.stream(excludedUserAgents).noneMatch((candidate) -> headers
|
||||
.contains(HttpHeaderNames.USER_AGENT, candidate, true));
|
||||
};
|
||||
}
|
||||
|
||||
private interface CompressionPredicate
|
||||
extends BiPredicate<HttpServerRequest, HttpServerResponse> {
|
||||
|
||||
static final CompressionPredicate ALWAYS = (request, response) -> true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ public abstract class AbstractReactiveWebServerFactoryTests {
|
||||
@Test
|
||||
public void noCompressionForMimeType() {
|
||||
Compression compression = new Compression();
|
||||
compression.setMimeTypes(new String[] {"application/json"});
|
||||
compression.setMimeTypes(new String[] { "application/json" });
|
||||
WebClient client = prepareCompressionTest(compression);
|
||||
ResponseEntity<Void> response = client.get().exchange()
|
||||
.flatMap((res) -> res.toEntity(Void.class)).block();
|
||||
@@ -297,7 +297,7 @@ public abstract class AbstractReactiveWebServerFactoryTests {
|
||||
public void noCompressionForUserAgent() {
|
||||
Compression compression = new Compression();
|
||||
compression.setEnabled(true);
|
||||
compression.setExcludedUserAgents(new String[] {"testUserAgent"});
|
||||
compression.setExcludedUserAgents(new String[] { "testUserAgent" });
|
||||
WebClient client = prepareCompressionTest(compression);
|
||||
ResponseEntity<Void> response = client.get().header("User-Agent", "testUserAgent")
|
||||
.exchange().flatMap((res) -> res.toEntity(Void.class)).block();
|
||||
|
||||
Reference in New Issue
Block a user