|
18 | 18 |
|
19 | 19 | import java.io.File;
|
20 | 20 | import java.io.IOException;
|
| 21 | +import java.time.Duration; |
21 | 22 | import java.util.ArrayList;
|
22 | 23 | import java.util.Arrays;
|
23 | 24 | import java.util.List;
|
| 25 | +import java.util.concurrent.BlockingQueue; |
| 26 | +import java.util.concurrent.SynchronousQueue; |
24 | 27 | import java.util.stream.Collectors;
|
25 | 28 |
|
26 | 29 | import org.eclipse.jetty.server.AbstractConnector;
|
|
30 | 33 | import org.eclipse.jetty.server.HttpConfiguration.ConnectionFactory;
|
31 | 34 | import org.eclipse.jetty.server.RequestLog;
|
32 | 35 | import org.eclipse.jetty.server.RequestLogWriter;
|
| 36 | +import org.eclipse.jetty.server.Server; |
| 37 | +import org.eclipse.jetty.util.BlockingArrayQueue; |
33 | 38 | import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
| 39 | +import org.eclipse.jetty.util.thread.ThreadPool; |
34 | 40 | import org.junit.jupiter.api.BeforeEach;
|
35 | 41 | import org.junit.jupiter.api.Test;
|
36 | 42 |
|
37 | 43 | import org.springframework.boot.autoconfigure.web.ServerProperties;
|
| 44 | +import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty; |
38 | 45 | import org.springframework.boot.context.properties.bind.Bindable;
|
39 | 46 | import org.springframework.boot.context.properties.bind.Binder;
|
40 | 47 | import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
|
43 | 50 | import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
44 | 51 | import org.springframework.mock.env.MockEnvironment;
|
45 | 52 | import org.springframework.test.context.support.TestPropertySourceUtils;
|
| 53 | +import org.springframework.test.util.ReflectionTestUtils; |
46 | 54 |
|
47 | 55 | import static org.assertj.core.api.Assertions.assertThat;
|
48 | 56 | import static org.mockito.Mockito.mock;
|
@@ -135,29 +143,100 @@ void accessLogCanBeEnabled() {
|
135 | 143 | }
|
136 | 144 |
|
137 | 145 | @Test
|
138 |
| - void maxThreadsCanBeCustomized() { |
| 146 | + void threadPoolMatchesJettyDefaults() { |
| 147 | + ThreadPool defaultThreadPool = new Server(0).getThreadPool(); |
| 148 | + ThreadPool configuredThreadPool = customizeAndGetServer().getServer().getThreadPool(); |
| 149 | + assertThat(defaultThreadPool).isInstanceOf(QueuedThreadPool.class); |
| 150 | + assertThat(configuredThreadPool).isInstanceOf(QueuedThreadPool.class); |
| 151 | + QueuedThreadPool defaultQueuedThreadPool = (QueuedThreadPool) defaultThreadPool; |
| 152 | + QueuedThreadPool configuredQueuedThreadPool = (QueuedThreadPool) configuredThreadPool; |
| 153 | + assertThat(configuredQueuedThreadPool.getMinThreads()).isEqualTo(defaultQueuedThreadPool.getMinThreads()); |
| 154 | + assertThat(configuredQueuedThreadPool.getMaxThreads()).isEqualTo(defaultQueuedThreadPool.getMaxThreads()); |
| 155 | + assertThat(configuredQueuedThreadPool.getIdleTimeout()).isEqualTo(defaultQueuedThreadPool.getIdleTimeout()); |
| 156 | + BlockingQueue<?> defaultQueue = getQueue(defaultThreadPool); |
| 157 | + BlockingQueue<?> configuredQueue = getQueue(configuredThreadPool); |
| 158 | + assertThat(defaultQueue).isInstanceOf(BlockingArrayQueue.class); |
| 159 | + assertThat(configuredQueue).isInstanceOf(BlockingArrayQueue.class); |
| 160 | + assertThat(((BlockingArrayQueue<?>) defaultQueue).getMaxCapacity()) |
| 161 | + .isEqualTo(((BlockingArrayQueue<?>) configuredQueue).getMaxCapacity()); |
| 162 | + } |
| 163 | + |
| 164 | + @Test |
| 165 | + void threadPoolMaxThreadsCanBeCustomized() { |
139 | 166 | bind("server.jetty.max-threads=100");
|
140 | 167 | JettyWebServer server = customizeAndGetServer();
|
141 | 168 | QueuedThreadPool threadPool = (QueuedThreadPool) server.getServer().getThreadPool();
|
142 | 169 | assertThat(threadPool.getMaxThreads()).isEqualTo(100);
|
143 | 170 | }
|
144 | 171 |
|
145 | 172 | @Test
|
146 |
| - void minThreadsCanBeCustomized() { |
| 173 | + void threadPoolMinThreadsCanBeCustomized() { |
147 | 174 | bind("server.jetty.min-threads=100");
|
148 | 175 | JettyWebServer server = customizeAndGetServer();
|
149 | 176 | QueuedThreadPool threadPool = (QueuedThreadPool) server.getServer().getThreadPool();
|
150 | 177 | assertThat(threadPool.getMinThreads()).isEqualTo(100);
|
151 | 178 | }
|
152 | 179 |
|
153 | 180 | @Test
|
154 |
| - void threadIdleTimeoutCanBeCustomized() { |
| 181 | + void threadPoolIdleTimeoutCanBeCustomized() { |
155 | 182 | bind("server.jetty.thread-idle-timeout=100s");
|
156 | 183 | JettyWebServer server = customizeAndGetServer();
|
157 | 184 | QueuedThreadPool threadPool = (QueuedThreadPool) server.getServer().getThreadPool();
|
158 | 185 | assertThat(threadPool.getIdleTimeout()).isEqualTo(100000);
|
159 | 186 | }
|
160 | 187 |
|
| 188 | + @Test |
| 189 | + void threadPoolWithMaxQueueCapacityEqualToZeroCreateSynchronousQueue() { |
| 190 | + bind("server.jetty.max-queue-capacity=0"); |
| 191 | + JettyWebServer server = customizeAndGetServer(); |
| 192 | + ThreadPool threadPool = server.getServer().getThreadPool(); |
| 193 | + BlockingQueue<?> queue = getQueue(threadPool); |
| 194 | + assertThat(queue).isInstanceOf(SynchronousQueue.class); |
| 195 | + assertDefaultThreadPoolSettings(threadPool); |
| 196 | + } |
| 197 | + |
| 198 | + @Test |
| 199 | + void threadPoolWithMaxQueueCapacityEqualToZeroCustomizesThreadPool() { |
| 200 | + bind("server.jetty.max-queue-capacity=0", "server.jetty.min-threads=100", "server.jetty.max-threads=100", |
| 201 | + "server.jetty.thread-idle-timeout=6s"); |
| 202 | + JettyWebServer server = customizeAndGetServer(); |
| 203 | + QueuedThreadPool threadPool = (QueuedThreadPool) server.getServer().getThreadPool(); |
| 204 | + assertThat(threadPool.getMinThreads()).isEqualTo(100); |
| 205 | + assertThat(threadPool.getMaxThreads()).isEqualTo(100); |
| 206 | + assertThat(threadPool.getIdleTimeout()).isEqualTo(Duration.ofSeconds(6).toMillis()); |
| 207 | + } |
| 208 | + |
| 209 | + @Test |
| 210 | + void threadPoolWithMaxQueueCapacityPositiveCreateBlockingArrayQueue() { |
| 211 | + bind("server.jetty.max-queue-capacity=1234"); |
| 212 | + JettyWebServer server = customizeAndGetServer(); |
| 213 | + ThreadPool threadPool = server.getServer().getThreadPool(); |
| 214 | + BlockingQueue<?> queue = getQueue(threadPool); |
| 215 | + assertThat(queue).isInstanceOf(BlockingArrayQueue.class); |
| 216 | + assertThat(((BlockingArrayQueue<?>) queue).getMaxCapacity()).isEqualTo(1234); |
| 217 | + assertDefaultThreadPoolSettings(threadPool); |
| 218 | + } |
| 219 | + |
| 220 | + @Test |
| 221 | + void threadPoolWithMaxQueueCapacityPositiveCustomizesThreadPool() { |
| 222 | + bind("server.jetty.max-queue-capacity=1234", "server.jetty.min-threads=10", "server.jetty.max-threads=150", |
| 223 | + "server.jetty.thread-idle-timeout=3s"); |
| 224 | + JettyWebServer server = customizeAndGetServer(); |
| 225 | + QueuedThreadPool threadPool = (QueuedThreadPool) server.getServer().getThreadPool(); |
| 226 | + assertThat(threadPool.getMinThreads()).isEqualTo(10); |
| 227 | + assertThat(threadPool.getMaxThreads()).isEqualTo(150); |
| 228 | + assertThat(threadPool.getIdleTimeout()).isEqualTo(Duration.ofSeconds(3).toMillis()); |
| 229 | + } |
| 230 | + |
| 231 | + private void assertDefaultThreadPoolSettings(ThreadPool threadPool) { |
| 232 | + assertThat(threadPool).isInstanceOf(QueuedThreadPool.class); |
| 233 | + QueuedThreadPool queuedThreadPool = (QueuedThreadPool) threadPool; |
| 234 | + Jetty defaultProperties = new Jetty(); |
| 235 | + assertThat(queuedThreadPool.getMinThreads()).isEqualTo(defaultProperties.getMinThreads()); |
| 236 | + assertThat(queuedThreadPool.getMaxThreads()).isEqualTo(defaultProperties.getMaxThreads()); |
| 237 | + assertThat(queuedThreadPool.getIdleTimeout()).isEqualTo(defaultProperties.getThreadIdleTimeout().toMillis()); |
| 238 | + } |
| 239 | + |
161 | 240 | private CustomRequestLog getRequestLog(JettyWebServer server) {
|
162 | 241 | RequestLog requestLog = server.getServer().getRequestLog();
|
163 | 242 | assertThat(requestLog).isInstanceOf(CustomRequestLog.class);
|
@@ -236,6 +315,10 @@ private List<Integer> getRequestHeaderSizes(JettyWebServer server) {
|
236 | 315 | return requestHeaderSizes;
|
237 | 316 | }
|
238 | 317 |
|
| 318 | + private BlockingQueue<?> getQueue(ThreadPool threadPool) { |
| 319 | + return ReflectionTestUtils.invokeMethod(threadPool, "getQueue"); |
| 320 | + } |
| 321 | + |
239 | 322 | private void bind(String... inlinedProperties) {
|
240 | 323 | TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties);
|
241 | 324 | new Binder(ConfigurationPropertySources.get(this.environment)).bind("server",
|
|
0 commit comments