pull/14847/head
Phillip Webb 7 years ago
parent 67998e983f
commit 7bc535e4fa

@ -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 (request, response) -> {
String contentType = response.responseHeaders()
.get(HttpHeaderNames.CONTENT_TYPE);
if (StringUtils.isEmpty(contentType)) {
return false;
}
return true;
}
MimeType contentMimeType = MimeTypeUtils.parseMimeType(contentType);
return Arrays.stream(mimeTypes).map(MimeTypeUtils::parseMimeType)
.anyMatch((candidate) -> candidate.isCompatibleWith(contentMimeType));
};
}
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]);
}
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));
};
}
@Override
public boolean test(HttpServerRequest request, HttpServerResponse 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;
}
}
}
return false;
}
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();

Loading…
Cancel
Save