Commit 208f5810 authored by cbono's avatar cbono Committed by Stephane Nicoll

Add 'threads' configuration group for embedded containers

See gh-19475
parent 5a687dfa
...@@ -76,11 +76,12 @@ public class JettyWebServerFactoryCustomizer ...@@ -76,11 +76,12 @@ public class JettyWebServerFactoryCustomizer
public void customize(ConfigurableJettyWebServerFactory factory) { public void customize(ConfigurableJettyWebServerFactory factory) {
ServerProperties properties = this.serverProperties; ServerProperties properties = this.serverProperties;
ServerProperties.Jetty jettyProperties = properties.getJetty(); ServerProperties.Jetty jettyProperties = properties.getJetty();
ServerProperties.Jetty.Threads threadProperties = jettyProperties.getThreads();
factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders()); factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders());
factory.setThreadPool(determineThreadPool(jettyProperties)); factory.setThreadPool(determineThreadPool(jettyProperties.getThreads()));
PropertyMapper propertyMapper = PropertyMapper.get(); PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(jettyProperties::getAcceptors).whenNonNull().to(factory::setAcceptors); propertyMapper.from(threadProperties::getAcceptors).whenNonNull().to(factory::setAcceptors);
propertyMapper.from(jettyProperties::getSelectors).whenNonNull().to(factory::setSelectors); propertyMapper.from(threadProperties::getSelectors).whenNonNull().to(factory::setSelectors);
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes) propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes)
.when(this::isPositive).to((maxHttpHeaderSize) -> factory .when(this::isPositive).to((maxHttpHeaderSize) -> factory
.addServerCustomizers(new MaxHttpHeaderSizeCustomizer(maxHttpHeaderSize))); .addServerCustomizers(new MaxHttpHeaderSizeCustomizer(maxHttpHeaderSize)));
...@@ -141,12 +142,12 @@ public class JettyWebServerFactoryCustomizer ...@@ -141,12 +142,12 @@ public class JettyWebServerFactoryCustomizer
}); });
} }
private ThreadPool determineThreadPool(ServerProperties.Jetty properties) { private ThreadPool determineThreadPool(ServerProperties.Jetty.Threads threadProperties) {
BlockingQueue<Runnable> queue = determineBlockingQueue(properties.getMaxQueueCapacity()); BlockingQueue<Runnable> queue = determineBlockingQueue(threadProperties.getMaxQueueCapacity());
int maxThreadCount = (properties.getMaxThreads() > 0) ? properties.getMaxThreads() : 200; int maxThreadCount = (threadProperties.getMax() > 0) ? threadProperties.getMax() : 200;
int minThreadCount = (properties.getMinThreads() > 0) ? properties.getMinThreads() : 8; int minThreadCount = (threadProperties.getMin() > 0) ? threadProperties.getMin() : 8;
int threadIdleTimeout = (properties.getThreadIdleTimeout() != null) int threadIdleTimeout = (threadProperties.getIdleTimeout() != null)
? (int) properties.getThreadIdleTimeout().toMillis() : 60000; ? (int) threadProperties.getIdleTimeout().toMillis() : 60000;
return new QueuedThreadPool(maxThreadCount, minThreadCount, threadIdleTimeout, queue); return new QueuedThreadPool(maxThreadCount, minThreadCount, threadIdleTimeout, queue);
} }
......
...@@ -79,14 +79,15 @@ public class TomcatWebServerFactoryCustomizer ...@@ -79,14 +79,15 @@ public class TomcatWebServerFactoryCustomizer
public void customize(ConfigurableTomcatWebServerFactory factory) { public void customize(ConfigurableTomcatWebServerFactory factory) {
ServerProperties properties = this.serverProperties; ServerProperties properties = this.serverProperties;
ServerProperties.Tomcat tomcatProperties = properties.getTomcat(); ServerProperties.Tomcat tomcatProperties = properties.getTomcat();
ServerProperties.Tomcat.Threads threadProperties = tomcatProperties.getThreads();
PropertyMapper propertyMapper = PropertyMapper.get(); PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(tomcatProperties::getBasedir).whenNonNull().to(factory::setBaseDirectory); propertyMapper.from(tomcatProperties::getBasedir).whenNonNull().to(factory::setBaseDirectory);
propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull().as(Duration::getSeconds) propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull().as(Duration::getSeconds)
.as(Long::intValue).to(factory::setBackgroundProcessorDelay); .as(Long::intValue).to(factory::setBackgroundProcessorDelay);
customizeRemoteIpValve(factory); customizeRemoteIpValve(factory);
propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive) propertyMapper.from(threadProperties::getMax).when(this::isPositive)
.to((maxThreads) -> customizeMaxThreads(factory, tomcatProperties.getMaxThreads())); .to((maxThreads) -> customizeMaxThreads(factory, threadProperties.getMax()));
propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive) propertyMapper.from(threadProperties::getMinSpare).when(this::isPositive)
.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads)); .to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
propertyMapper.from(this.serverProperties.getMaxHttpHeaderSize()).whenNonNull().asInt(DataSize::toBytes) propertyMapper.from(this.serverProperties.getMaxHttpHeaderSize()).whenNonNull().asInt(DataSize::toBytes)
.when(this::isPositive) .when(this::isPositive)
......
...@@ -88,9 +88,10 @@ public class UndertowWebServerFactoryCustomizer ...@@ -88,9 +88,10 @@ public class UndertowWebServerFactoryCustomizer
private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, FactoryOptions options) { private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, FactoryOptions options) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
Undertow properties = this.serverProperties.getUndertow(); Undertow properties = this.serverProperties.getUndertow();
ServerProperties.Undertow.Threads threadProperties = properties.getThreads();
map.from(properties::getBufferSize).whenNonNull().asInt(DataSize::toBytes).to(factory::setBufferSize); map.from(properties::getBufferSize).whenNonNull().asInt(DataSize::toBytes).to(factory::setBufferSize);
map.from(properties::getIoThreads).to(factory::setIoThreads); map.from(threadProperties::getIo).to(factory::setIoThreads);
map.from(properties::getWorkerThreads).to(factory::setWorkerThreads); map.from(threadProperties::getWorker).to(factory::setWorkerThreads);
map.from(properties::getDirectBuffers).to(factory::setUseDirectBuffers); map.from(properties::getDirectBuffers).to(factory::setUseDirectBuffers);
map.from(properties::getMaxHttpPostSize).as(DataSize::toBytes).when(this::isPositive) map.from(properties::getMaxHttpPostSize).as(DataSize::toBytes).when(this::isPositive)
.to(options.server(UndertowOptions.MAX_ENTITY_SIZE)); .to(options.server(UndertowOptions.MAX_ENTITY_SIZE));
......
...@@ -20,6 +20,7 @@ import java.io.IOException; ...@@ -20,6 +20,7 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -75,6 +76,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -75,6 +76,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andrew McGhie * @author Andrew McGhie
* @author HaiTao Zhang * @author HaiTao Zhang
* @author Rafiullah Hamedy * @author Rafiullah Hamedy
* @author Chris Bono
*/ */
class ServerPropertiesTests { class ServerPropertiesTests {
...@@ -207,40 +209,132 @@ class ServerPropertiesTests { ...@@ -207,40 +209,132 @@ class ServerPropertiesTests {
assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(1)); assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(1));
} }
@Test
void testCustomizeTomcatMaxThreads() {
bind("server.tomcat.threads.max", "10");
assertThat(this.properties.getTomcat().getThreads().getMax()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeTomcatMaxThreadsDeprecated() {
bind("server.tomcat.maxThreads", "10");
assertThat(this.properties.getTomcat().getMaxThreads()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getTomcat().getThreads().getMax()).isEqualTo(10);
}
@Test
void testCustomizeTomcatMinSpareThreads() {
bind("server.tomcat.threads.min-spare", "10");
assertThat(this.properties.getTomcat().getThreads().getMinSpare()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeTomcatMinSpareThreadsDeprecated() {
bind("server.tomcat.min-spare-threads", "10");
assertThat(this.properties.getTomcat().getMinSpareThreads()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getTomcat().getThreads().getMinSpare()).isEqualTo(10);
}
@Test @Test
void testCustomizeJettyAcceptors() { void testCustomizeJettyAcceptors() {
bind("server.jetty.threads.acceptors", "10");
assertThat(this.properties.getJetty().getThreads().getAcceptors()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeJettyAcceptorsDeprecated() {
bind("server.jetty.acceptors", "10"); bind("server.jetty.acceptors", "10");
assertThat(this.properties.getJetty().getAcceptors()).isEqualTo(10); assertThat(this.properties.getJetty().getAcceptors()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getAcceptors()).isEqualTo(10);
} }
@Test @Test
void testCustomizeJettySelectors() { void testCustomizeJettySelectors() {
bind("server.jetty.threads.selectors", "10");
assertThat(this.properties.getJetty().getThreads().getSelectors()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeJettySelectorsDeprecated() {
bind("server.jetty.selectors", "10"); bind("server.jetty.selectors", "10");
assertThat(this.properties.getJetty().getSelectors()).isEqualTo(10); assertThat(this.properties.getJetty().getSelectors()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getSelectors()).isEqualTo(10);
} }
@Test @Test
void testCustomizeJettyMaxThreads() { void testCustomizeJettyMaxThreads() {
bind("server.jetty.max-threads", "10"); bind("server.jetty.threads.max", "10");
assertThat(this.properties.getJetty().getThreads().getMax()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeJettyMaxThreadsDeprecated() {
bind("server.jetty.maxThreads", "10");
assertThat(this.properties.getJetty().getMaxThreads()).isEqualTo(10); assertThat(this.properties.getJetty().getMaxThreads()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getMax()).isEqualTo(10);
} }
@Test @Test
void testCustomizeJettyMinThreads() { void testCustomizeJettyMinThreads() {
bind("server.jetty.min-threads", "10"); bind("server.jetty.threads.min", "10");
assertThat(this.properties.getJetty().getThreads().getMin()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeJettyMinThreadsDeprecated() {
bind("server.jetty.minThreads", "10");
assertThat(this.properties.getJetty().getMinThreads()).isEqualTo(10); assertThat(this.properties.getJetty().getMinThreads()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getMin()).isEqualTo(10);
} }
@Test @Test
void testCustomizeJettyIdleTimeout() { void testCustomizeJettyIdleTimeout() {
bind("server.jetty.threads.idle-timeout", "10s");
assertThat(this.properties.getJetty().getThreads().getIdleTimeout()).isEqualTo(Duration.ofSeconds(10));
}
@Deprecated
@Test
void testCustomizeJettyIdleTimeoutDeprecated() {
bind("server.jetty.thread-idle-timeout", "10s"); bind("server.jetty.thread-idle-timeout", "10s");
assertThat(this.properties.getJetty().getThreadIdleTimeout()).hasSeconds(10); assertThat(this.properties.getJetty().getThreadIdleTimeout()).isEqualTo(Duration.ofSeconds(10));
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getIdleTimeout()).hasSeconds(10);
} }
@Test @Test
void testCustomizeJettyMaxQueueCapacity() { void testCustomizeJettyMaxQueueCapacity() {
bind("server.jetty.threads.max-queue-capacity", "5150");
assertThat(this.properties.getJetty().getThreads().getMaxQueueCapacity()).isEqualTo(5150);
}
@Deprecated
@Test
void testCustomizeJettyMaxQueueCapacityDeprecated() {
bind("server.jetty.max-queue-capacity", "5150"); bind("server.jetty.max-queue-capacity", "5150");
assertThat(this.properties.getJetty().getMaxQueueCapacity()).isEqualTo(5150); assertThat(this.properties.getJetty().getMaxQueueCapacity()).isEqualTo(5150);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getJetty().getThreads().getMaxQueueCapacity()).isEqualTo(5150);
} }
@Test @Test
...@@ -257,6 +351,38 @@ class ServerPropertiesTests { ...@@ -257,6 +351,38 @@ class ServerPropertiesTests {
"true"); "true");
} }
@Test
void testCustomizeUndertowIoThreads() {
bind("server.undertow.threads.io", "4");
assertThat(this.properties.getUndertow().getThreads().getIo()).isEqualTo(4);
}
@Deprecated
@Test
void testCustomizeUndertowIoThreadsDeprecated() {
bind("server.undertow.ioThreads", "4");
assertThat(this.properties.getUndertow().getIoThreads()).isEqualTo(4);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getUndertow().getThreads().getIo()).isEqualTo(4);
}
@Test
void testCustomizeUndertowWorkerThreads() {
bind("server.undertow.threads.worker", "10");
assertThat(this.properties.getUndertow().getThreads().getWorker()).isEqualTo(10);
}
@Deprecated
@Test
void testCustomizeUndertowWorkerThreadsDeprecated() {
bind("server.undertow.workerThreads", "10");
assertThat(this.properties.getUndertow().getWorkerThreads()).isEqualTo(10);
// Verify they are locked on same backing props to avoid further downstream
// deprecated testing
assertThat(this.properties.getUndertow().getThreads().getWorker()).isEqualTo(10);
}
@Test @Test
void testCustomizeJettyAccessLog() { void testCustomizeJettyAccessLog() {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
...@@ -295,12 +421,12 @@ class ServerPropertiesTests { ...@@ -295,12 +421,12 @@ class ServerPropertiesTests {
@Test @Test
void tomcatMaxThreadsMatchesProtocolDefault() throws Exception { void tomcatMaxThreadsMatchesProtocolDefault() throws Exception {
assertThat(this.properties.getTomcat().getMaxThreads()).isEqualTo(getDefaultProtocol().getMaxThreads()); assertThat(this.properties.getTomcat().getThreads().getMax()).isEqualTo(getDefaultProtocol().getMaxThreads());
} }
@Test @Test
void tomcatMinSpareThreadsMatchesProtocolDefault() throws Exception { void tomcatMinSpareThreadsMatchesProtocolDefault() throws Exception {
assertThat(this.properties.getTomcat().getMinSpareThreads()) assertThat(this.properties.getTomcat().getThreads().getMinSpare())
.isEqualTo(getDefaultProtocol().getMinSpareThreads()); .isEqualTo(getDefaultProtocol().getMinSpareThreads());
} }
......
...@@ -345,8 +345,8 @@ class TomcatWebServerFactoryCustomizerTests { ...@@ -345,8 +345,8 @@ class TomcatWebServerFactoryCustomizerTests {
@Test @Test
void testCustomizeMinSpareThreads() { void testCustomizeMinSpareThreads() {
bind("server.tomcat.min-spare-threads=10"); bind("server.tomcat.threads.min-spare=10");
assertThat(this.serverProperties.getTomcat().getMinSpareThreads()).isEqualTo(10); assertThat(this.serverProperties.getTomcat().getThreads().getMinSpare()).isEqualTo(10);
} }
@Test @Test
......
...@@ -132,6 +132,22 @@ class UndertowWebServerFactoryCustomizerTests { ...@@ -132,6 +132,22 @@ class UndertowWebServerFactoryCustomizerTests {
assertThat(boundServerOption(UndertowOptions.MAX_COOKIES)).isEqualTo(4); assertThat(boundServerOption(UndertowOptions.MAX_COOKIES)).isEqualTo(4);
} }
@Test
void customizeIoThreads() {
bind("server.undertow.threads.io=4");
ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class);
this.customizer.customize(factory);
verify(factory).setIoThreads(4);
}
@Test
void customizeWorkerThreads() {
bind("server.undertow.threads.worker=10");
ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class);
this.customizer.customize(factory);
verify(factory).setWorkerThreads(10);
}
@Test @Test
void allowEncodedSlashes() { void allowEncodedSlashes() {
bind("server.undertow.allow-encoded-slash=true"); bind("server.undertow.allow-encoded-slash=true");
......
...@@ -139,9 +139,9 @@ class ServletWebServerFactoryCustomizerTests { ...@@ -139,9 +139,9 @@ class ServletWebServerFactoryCustomizerTests {
@Test @Test
void testCustomizeTomcatMinSpareThreads() { void testCustomizeTomcatMinSpareThreads() {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("server.tomcat.min-spare-threads", "10"); map.put("server.tomcat.threads.min-spare", "10");
bindProperties(map); bindProperties(map);
assertThat(this.properties.getTomcat().getMinSpareThreads()).isEqualTo(10); assertThat(this.properties.getTomcat().getThreads().getMinSpare()).isEqualTo(10);
} }
@Test @Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment