From 8c0051a02e8fa78635b4a3112a3405b7c0f2f37b Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 20 Aug 2025 09:25:05 +0200 Subject: [PATCH] Drop Undertow support Spring Framework 7.0 requires a Servlet 6.1 baseline for Servlet containers. Partial Servlet 6.1 support is available on the `main` Undertow branch, but there isn't any milestone version available for the undertow 2.4 generation. At this stage of our 4.0 schedule, we think it's safer to drop Undertow support now. Closes: gh-46917 --- README.adoc | 2 +- .../build.gradle | 1 - documentation/spring-boot-docs/build.gradle | 2 - .../antora/modules/ROOT/pages/redirect.adoc | 4 - .../ROOT/pages/system-requirements.adoc | 2 - .../how-to/pages/deployment/cloud.adoc | 2 +- .../modules/how-to/pages/webserver.adoc | 55 +- .../reference/pages/messaging/websockets.adoc | 2 +- .../pages/web/graceful-shutdown.adoc | 5 +- .../modules/reference/pages/web/index.adoc | 2 +- .../modules/reference/pages/web/reactive.adoc | 4 +- .../modules/reference/pages/web/servlet.adoc | 12 +- .../MyUndertowConfiguration.java | 38 -- .../MyUndertowConfiguration.kt | 42 -- .../build.gradle | 2 - .../build.gradle | 9 +- .../spring-boot-server-tests-app/build.gradle | 6 +- ...verContainerInvocationContextProvider.java | 2 +- .../build.gradle | 11 +- .../spring-boot-sni-reactive-app/build.gradle | 6 +- .../spring-boot-sni-servlet-app/build.gradle | 6 +- .../boot/sni/SniIntegrationTests.java | 4 +- .../build.gradle | 3 - .../servlet/JettyEmbeddedErrorHandler.java | 2 +- module/spring-boot-servlet/build.gradle | 1 - .../MultipartAutoConfigurationTests.java | 74 +-- module/spring-boot-undertow/build.gradle | 54 -- .../undertow/AccessLogHttpHandlerFactory.java | 120 ---- .../CompressionHttpHandlerFactory.java | 135 ---- .../ConfigurableUndertowWebServerFactory.java | 116 ---- .../boot/undertow/HttpHandlerFactory.java | 49 -- .../boot/undertow/SslBuilderCustomizer.java | 94 --- .../undertow/UndertowBuilderCustomizer.java | 39 -- .../boot/undertow/UndertowWebServer.java | 484 -------------- .../undertow/UndertowWebServerFactory.java | 237 ------- .../UndertowServerProperties.java | 406 ------------ .../UndertowWebServerConfiguration.java | 42 -- .../UndertowWebServerFactoryCustomizer.java | 239 ------- .../server/UndertowAccessLogCustomizer.java | 47 -- .../UndertowManagementServerProperties.java | 53 -- ...veManagementChildContextConfiguration.java | 59 -- ...iveManagementContextAutoConfiguration.java | 51 -- ...etManagementChildContextConfiguration.java | 49 -- ...letManagementContextAutoConfiguration.java | 51 -- .../actuate/web/server/package-info.java | 23 - .../undertow/autoconfigure/package-info.java | 24 - ...towReactiveWebServerAutoConfiguration.java | 62 -- .../autoconfigure/reactive/package-info.java | 23 - ...rtowServletWebServerAutoConfiguration.java | 97 --- ...rtowServletWebServerFactoryCustomizer.java | 44 -- ...rtowServletWebServerFactoryCustomizer.java | 57 -- .../autoconfigure/servlet/package-info.java | 23 - .../boot/undertow/package-info.java | 26 - .../UndertowReactiveWebServerFactory.java | 65 -- .../boot/undertow/reactive/package-info.java | 23 - .../servlet/CompositeResourceManager.java | 75 --- .../DeploymentManagerHttpHandlerFactory.java | 96 --- .../servlet/FileSessionPersistence.java | 148 ----- .../undertow/servlet/JarResourceManager.java | 83 --- .../UndertowDeploymentInfoCustomizer.java | 37 -- .../servlet/UndertowServletWebServer.java | 96 --- .../UndertowServletWebServerFactory.java | 608 ------------------ .../boot/undertow/servlet/package-info.java | 23 - .../META-INF/META-INF/spring.factories | 0 ...itional-spring-configuration-metadata.json | 13 - .../resources/META-INF/spring/aot.factories | 2 - ...web.ManagementContextConfiguration.imports | 2 - ...ot.autoconfigure.AutoConfiguration.imports | 4 - .../boot/undertow/UndertowAccess.java | 34 - .../UndertowWebServerRuntimeHintsTests.java | 57 -- .../UndertowServerPropertiesTests.java | 79 --- ...dertowWebServerFactoryCustomizerTests.java | 268 -------- ...dertowManagementServerPropertiesTests.java | 38 -- ...activeWebServerAutoConfigurationTests.java | 109 ---- ...ervletWebServerAutoConfigurationTests.java | 158 ----- ...ervletWebServerFactoryCustomizerTests.java | 53 -- ...tWebServerServletContextListenerTests.java | 47 -- ...UndertowReactiveWebServerFactoryTests.java | 173 ----- .../servlet/FileSessionPersistenceTests.java | 97 --- .../servlet/JarResourceManagerTests.java | 103 --- .../UndertowServletWebServerFactoryTests.java | 399 ------------ ...owServletWebServerMvcIntegrationTests.java | 45 -- .../boot/undertow/servlet/restricted.jks | Bin 4464 -> 0 bytes .../boot/undertow/servlet/test.jks | Bin 6536 -> 0 bytes .../springframework/boot/undertow/test.jks | Bin 6536 -> 0 bytes ...AbstractReactiveWebServerFactoryTests.java | 6 +- .../AbstractServletWebServerFactoryTests.java | 6 +- module/spring-boot-webmvc/build.gradle | 1 - .../DispatcherServletHandlerMappings.java | 33 +- .../spring-boot-dependencies/build.gradle | 14 - settings.gradle | 5 - .../build.gradle | 32 - .../ssl/SampleUndertowSslApplication.java | 29 - .../smoketest/undertow/ssl/package-info.java | 20 - .../undertow/ssl/web/SampleController.java | 30 - .../undertow/ssl/web/package-info.java | 20 - .../src/main/resources/application.properties | 4 - .../src/main/resources/sample.jks | Bin 2264 -> 0 bytes .../SampleUndertowSslApplicationTests.java | 57 -- .../build.gradle | 31 - .../undertow/SampleUndertowApplication.java | 29 - .../java/smoketest/undertow/package-info.java | 20 - .../undertow/web/SampleController.java | 37 -- .../smoketest/undertow/web/package-info.java | 20 - .../src/main/resources/application.properties | 5 - .../SampleUndertowApplicationTests.java | 79 --- .../build.gradle | 30 - .../SampleUndertowWebSocketsApplication.java | 90 --- .../undertow/client/GreetingService.java | 23 - .../client/SimpleClientWebSocketHandler.java | 60 -- .../client/SimpleGreetingService.java | 26 - .../undertow/client/package-info.java | 20 - .../undertow/echo/DefaultEchoService.java | 34 - .../websocket/undertow/echo/EchoService.java | 23 - .../undertow/echo/EchoWebSocketHandler.java | 58 -- .../websocket/undertow/echo/package-info.java | 20 - .../websocket/undertow/package-info.java | 20 - .../reverse/ReverseWebSocketEndpoint.java | 33 - .../undertow/reverse/package-info.java | 20 - .../websocket/undertow/snake/Direction.java | 23 - .../websocket/undertow/snake/Location.java | 70 -- .../websocket/undertow/snake/Snake.java | 156 ----- .../websocket/undertow/snake/SnakeTimer.java | 118 ---- .../websocket/undertow/snake/SnakeUtils.java | 66 -- .../undertow/snake/SnakeWebSocketHandler.java | 102 --- .../undertow/snake/package-info.java | 20 - .../src/main/resources/static/echo.html | 134 ---- .../src/main/resources/static/index.html | 33 - .../src/main/resources/static/reverse.html | 141 ---- .../src/main/resources/static/snake.html | 250 ------- .../SampleWebSocketsApplicationTests.java | 124 ---- ...omContainerWebSocketsApplicationTests.java | 141 ---- .../undertow/snake/SnakeTimerTests.java | 39 -- .../spring-boot-starter-undertow/build.gradle | 31 - 134 files changed, 43 insertions(+), 8278 deletions(-) delete mode 100644 documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.java delete mode 100644 documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt delete mode 100644 module/spring-boot-undertow/build.gradle delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowAccessLogCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowManagementServerProperties.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementChildContextConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementContextAutoConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementChildContextConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementContextAutoConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java delete mode 100644 module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java delete mode 100644 module/spring-boot-undertow/src/main/resources/META-INF/META-INF/spring.factories delete mode 100644 module/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 module/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories delete mode 100644 module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports delete mode 100644 module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java delete mode 100644 module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java delete mode 100644 module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/restricted.jks delete mode 100644 module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/test.jks delete mode 100644 module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/test.jks delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/build.gradle delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/SampleUndertowSslApplication.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/SampleController.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/application.properties delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/sample.jks delete mode 100644 smoke-test/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/build.gradle delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/SampleUndertowApplication.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/SampleController.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/main/resources/application.properties delete mode 100644 smoke-test/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/build.gradle delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/SampleUndertowWebSocketsApplication.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/GreetingService.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleClientWebSocketHandler.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleGreetingService.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/DefaultEchoService.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoService.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoWebSocketHandler.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/ReverseWebSocketEndpoint.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Direction.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Location.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Snake.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeTimer.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeUtils.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeWebSocketHandler.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/package-info.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/echo.html delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/index.html delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/reverse.html delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/snake.html delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java delete mode 100644 smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/snake/SnakeTimerTests.java delete mode 100644 starter/spring-boot-starter-undertow/build.gradle diff --git a/README.adoc b/README.adoc index 2f877b90956..c34f3570361 100755 --- a/README.adoc +++ b/README.adoc @@ -116,7 +116,7 @@ The main library providing features that support the other parts of Spring Boot. * The `SpringApplication` class, providing static convenience methods that can be used to write a stand-alone Spring Application. Its sole job is to create and refresh an appropriate Spring `ApplicationContext`. -* Embedded web applications with a choice of container (Tomcat, Jetty, or Undertow). +* Embedded web applications with a choice of container (Tomcat, Jetty). * First-class externalized configuration support. * Convenience `ApplicationContext` initializers, including support for sensible logging defaults. diff --git a/configuration-metadata/spring-boot-configuration-metadata-changelog-generator/build.gradle b/configuration-metadata/spring-boot-configuration-metadata-changelog-generator/build.gradle index 93ae797ca26..dae95417f8b 100644 --- a/configuration-metadata/spring-boot-configuration-metadata-changelog-generator/build.gradle +++ b/configuration-metadata/spring-boot-configuration-metadata-changelog-generator/build.gradle @@ -128,7 +128,6 @@ def dependenciesOf(String version) { "spring-boot-tomcat", "spring-boot-tracing", "spring-boot-tx", - "spring-boot-undertow", "spring-boot-validation", "spring-boot-web-server", "spring-boot-webclient", diff --git a/documentation/spring-boot-docs/build.gradle b/documentation/spring-boot-docs/build.gradle index 7c4e8903ba9..4d97961b9a1 100644 --- a/documentation/spring-boot-docs/build.gradle +++ b/documentation/spring-boot-docs/build.gradle @@ -111,7 +111,6 @@ dependencies { implementation(project(path: ":module:spring-boot-security")) implementation(project(path: ":module:spring-boot-test-autoconfigure")) implementation(project(path: ":module:spring-boot-tomcat")) - implementation(project(path: ":module:spring-boot-undertow")) implementation(project(path: ":module:spring-boot-web-server-test")) implementation(project(path: ":module:spring-boot-webclient")) implementation(project(path: ":module:spring-boot-webflux")) @@ -126,7 +125,6 @@ dependencies { implementation("io.micrometer:micrometer-registry-jmx") implementation("io.opentelemetry.instrumentation:opentelemetry-logback-appender-1.0") implementation("io.projectreactor.netty:reactor-netty-http") - implementation("io.undertow:undertow-core") implementation("jakarta.annotation:jakarta.annotation-api") implementation("jakarta.jms:jakarta.jms-api") implementation("jakarta.persistence:jakarta.persistence-api") diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc index fea1f7a5046..fb286948139 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/redirect.adoc @@ -684,8 +684,6 @@ * xref:how-to:webserver.adoc#howto.webserver.configure-http2.netty[#howto.webserver.configure-http2.netty] * xref:how-to:webserver.adoc#howto.webserver.configure-http2.tomcat[#howto-configure-http2-tomcat] * xref:how-to:webserver.adoc#howto.webserver.configure-http2.tomcat[#howto.webserver.configure-http2.tomcat] -* xref:how-to:webserver.adoc#howto.webserver.configure-http2.undertow[#howto-configure-http2-undertow] -* xref:how-to:webserver.adoc#howto.webserver.configure-http2.undertow[#howto.webserver.configure-http2.undertow] * xref:how-to:webserver.adoc#howto.webserver.configure-http2[#howto-configure-http2] * xref:how-to:webserver.adoc#howto.webserver.configure-http2[#howto.webserver.configure-http2] * xref:how-to:webserver.adoc#howto.webserver.configure-ssl.pem-files[#howto.webserver.configure-ssl.pem-files] @@ -701,8 +699,6 @@ * xref:how-to:webserver.adoc#howto.webserver.discover-port[#howto.webserver.discover-port] * xref:how-to:webserver.adoc#howto.webserver.enable-multiple-connectors-in-tomcat[#howto-enable-multiple-connectors-in-tomcat] * xref:how-to:webserver.adoc#howto.webserver.enable-multiple-connectors-in-tomcat[#howto.webserver.enable-multiple-connectors-in-tomcat] -* xref:how-to:webserver.adoc#howto.webserver.enable-multiple-listeners-in-undertow[#howto-enable-multiple-listeners-in-undertow] -* xref:how-to:webserver.adoc#howto.webserver.enable-multiple-listeners-in-undertow[#howto.webserver.enable-multiple-listeners-in-undertow] * xref:how-to:webserver.adoc#howto.webserver.enable-response-compression[#how-to-enable-http-response-compression] * xref:how-to:webserver.adoc#howto.webserver.enable-response-compression[#howto.webserver.enable-response-compression] * xref:how-to:webserver.adoc#howto.webserver.enable-tomcat-mbean-registry[#howto-enable-tomcat-mbean-registry] diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/system-requirements.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/system-requirements.adoc index 7f89b4db3f2..fd9bd5931ff 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/system-requirements.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/system-requirements.adoc @@ -32,8 +32,6 @@ Spring Boot supports the following embedded servlet containers: | Jetty 12.0 | 6.0 -| Undertow 2.3 -| 6.0 |=== You can also deploy Spring Boot applications to any servlet 5.0+ compatible container. diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/cloud.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/cloud.adoc index d1e3bcb83d9..bf53d281f12 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/cloud.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/cloud.adoc @@ -179,7 +179,7 @@ web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar ---- Spring Boot makes `-D` arguments available as properties accessible from a Spring javadoc:org.springframework.core.env.Environment[] instance. -The `server.port` configuration property is fed to the embedded Tomcat, Jetty, or Undertow instance, which then uses the port when it starts up. +The `server.port` configuration property is fed to the embedded Tomcat or Jetty instance, which then uses the port when it starts up. The `$PORT` environment variable is assigned to us by the Heroku PaaS. This should be everything you need. diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc index b51b7606a56..469f6eeffed 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc @@ -12,8 +12,8 @@ This section answers those questions. Many Spring Boot starters include default embedded containers. -* For servlet stack applications, the `spring-boot-starter-web` includes Tomcat by including `spring-boot-starter-tomcat`, but you can use `spring-boot-starter-jetty` or `spring-boot-starter-undertow` instead. -* For reactive stack applications, the `spring-boot-starter-webflux` includes Reactor Netty by including `spring-boot-starter-reactor-netty`, but you can use `spring-boot-starter-tomcat`, `spring-boot-starter-jetty`, or `spring-boot-starter-undertow` instead. +* For servlet stack applications, the `spring-boot-starter-web` includes Tomcat by including `spring-boot-starter-tomcat`, but you can use `spring-boot-starter-jetty` instead. +* For reactive stack applications, the `spring-boot-starter-webflux` includes Reactor Netty by including `spring-boot-starter-reactor-netty`, but you can use `spring-boot-starter-tomcat` or `spring-boot-starter-jetty` instead. When switching to a different HTTP server, you need to swap the default dependencies for those that you need instead. To help with this process, Spring Boot provides a separate starter for each of the supported HTTP servers. @@ -40,16 +40,16 @@ The following Maven example shows how to exclude Tomcat and include Jetty for Sp ---- -The following Gradle example configures the necessary dependencies and a {url-gradle-docs}/resolution_rules.html#sec:module_replacement[module replacement] to use Undertow in place of Reactor Netty for Spring WebFlux: +The following Gradle example configures the necessary dependencies and a {url-gradle-docs}/resolution_rules.html#sec:module_replacement[module replacement] to use Tomcat in place of Reactor Netty for Spring WebFlux: [source,gradle] ---- dependencies { - implementation "org.springframework.boot:spring-boot-starter-undertow" + implementation "org.springframework.boot:spring-boot-starter-tomcat" implementation "org.springframework.boot:spring-boot-starter-webflux" modules { module("org.springframework.boot:spring-boot-starter-reactor-netty") { - replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty") + replacedBy("org.springframework.boot:spring-boot-starter-tomcat", "Use Tomcat instead of Reactor Netty") } } } @@ -116,7 +116,7 @@ Contrary to a test, application code callbacks are processed early (before the v [[howto.webserver.enable-response-compression]] == Enable HTTP Response Compression -HTTP response compression is supported by Jetty, Tomcat, Reactor Netty, and Undertow. +HTTP response compression is supported by Jetty, Tomcat and Reactor Netty. It can be enabled in `application.properties`, as follows: [configprops,yaml] @@ -221,7 +221,7 @@ These properties should instead be defined using `spring.ssl.bundle.. undertowListenerCustomizer() { - return (factory) -> factory.addBuilderCustomizers(this::addHttpListener); - } - - private Builder addHttpListener(Builder builder) { - return builder.addHttpListener(8080, "0.0.0.0"); - } - -} diff --git a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt b/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt deleted file mode 100644 index dbe48766915..00000000000 --- a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docs.howto.webserver.enablemultiplelistenersinundertow - -import io.undertow.Undertow -import org.springframework.boot.web.server.WebServerFactoryCustomizer -import org.springframework.boot.undertow.UndertowBuilderCustomizer -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration(proxyBeanMethods = false) -class MyUndertowConfiguration { - - @Bean - fun undertowListenerCustomizer(): WebServerFactoryCustomizer { - return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory -> - factory.addBuilderCustomizers( - UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) }) - } - } - - private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder { - return builder.addHttpListener(8080, "0.0.0.0") - } - -} - diff --git a/integration-test/spring-boot-integration-tests/build.gradle b/integration-test/spring-boot-integration-tests/build.gradle index 267621c4474..0ff8c625883 100644 --- a/integration-test/spring-boot-integration-tests/build.gradle +++ b/integration-test/spring-boot-integration-tests/build.gradle @@ -26,7 +26,6 @@ dependencies { testImplementation(project(":module:spring-boot-jetty")) testImplementation(project(":module:spring-boot-tomcat")) testImplementation(project(":test-support:spring-boot-test-support")) - testImplementation(project(":module:spring-boot-undertow")) testImplementation("io.projectreactor.netty:reactor-netty-http") testImplementation("org.apache.httpcomponents.client5:httpclient5") testImplementation("org.apache.httpcomponents.core5:httpcore5-reactive") @@ -36,7 +35,6 @@ dependencies { testImplementation("org.springframework:spring-webmvc") testRuntimeOnly("ch.qos.logback:logback-classic") - testRuntimeOnly("io.undertow:undertow-servlet") testRuntimeOnly("org.eclipse.jetty.ee11:jetty-ee11-servlets") testRuntimeOnly("org.eclipse.jetty.ee11:jetty-ee11-webapp") } diff --git a/integration-test/spring-boot-server-integration-tests/build.gradle b/integration-test/spring-boot-server-integration-tests/build.gradle index 677a4007b4a..817d43b2fb4 100644 --- a/integration-test/spring-boot-server-integration-tests/build.gradle +++ b/integration-test/spring-boot-server-integration-tests/build.gradle @@ -38,7 +38,6 @@ dependencies { testRepository(project(path: ":starter:spring-boot-starter-jackson", configuration: "mavenRepository")) testRepository(project(path: ":starter:spring-boot-starter-parent", configuration: "mavenRepository")) testRepository(project(path: ":starter:spring-boot-starter-tomcat", configuration: "mavenRepository")) - testRepository(project(path: ":starter:spring-boot-starter-undertow", configuration: "mavenRepository")) testRuntimeOnly(project(":starter:spring-boot-starter-logging")) } @@ -63,9 +62,7 @@ tasks.register("buildApps", GradleBuild) { "jettyBootJar", "jettyBootWar", "tomcatBootJar", - "tomcatBootWar", - "undertowBootJar", - "undertowBootWar" + "tomcatBootWar" ] } @@ -75,9 +72,7 @@ intTest { layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-jetty.war"), layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-resources.jar"), layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat.jar"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat.war"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-undertow.jar"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-undertow.war") + layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat.war") ) .withPropertyName("applicationArchives") .withPathSensitivity(PathSensitivity.RELATIVE) diff --git a/integration-test/spring-boot-server-integration-tests/spring-boot-server-tests-app/build.gradle b/integration-test/spring-boot-server-integration-tests/spring-boot-server-tests-app/build.gradle index 494df11900d..53f2da6af4b 100644 --- a/integration-test/spring-boot-server-integration-tests/spring-boot-server-tests-app/build.gradle +++ b/integration-test/spring-boot-server-integration-tests/spring-boot-server-tests-app/build.gradle @@ -44,9 +44,6 @@ configurations { tomcat { extendsFrom(app) } - undertow { - extendsFrom(app) - } } tasks.register("resourcesJar", Jar) { jar -> @@ -77,14 +74,13 @@ dependencies { app("org.springframework:spring-web") jetty("org.springframework.boot:spring-boot-starter-jetty") tomcat("org.springframework.boot:spring-boot-starter-tomcat") - undertow("org.springframework.boot:spring-boot-starter-undertow") } static boolean isWindows() { return File.separatorChar == '\\' } -["jetty", "tomcat", "undertow"].each { webServer -> +["jetty", "tomcat"].each { webServer -> def configurer = { task -> task.dependsOn resourcesJar task.mainClass = "com.example.ResourceHandlingApplication" diff --git a/integration-test/spring-boot-server-integration-tests/src/intTest/java/org/springframework/boot/context/embedded/EmbeddedServerContainerInvocationContextProvider.java b/integration-test/spring-boot-server-integration-tests/src/intTest/java/org/springframework/boot/context/embedded/EmbeddedServerContainerInvocationContextProvider.java index 73328cdde60..b5120389081 100644 --- a/integration-test/spring-boot-server-integration-tests/src/intTest/java/org/springframework/boot/context/embedded/EmbeddedServerContainerInvocationContextProvider.java +++ b/integration-test/spring-boot-server-integration-tests/src/intTest/java/org/springframework/boot/context/embedded/EmbeddedServerContainerInvocationContextProvider.java @@ -62,7 +62,7 @@ import org.springframework.web.util.UriTemplateHandler; class EmbeddedServerContainerInvocationContextProvider implements TestTemplateInvocationContextProvider, AfterAllCallback { - private static final Set CONTAINERS = new HashSet<>(Arrays.asList("jetty", "tomcat", "undertow")); + private static final Set CONTAINERS = new HashSet<>(Arrays.asList("jetty", "tomcat")); private static final BuildOutput buildOutput = new BuildOutput( EmbeddedServerContainerInvocationContextProvider.class); diff --git a/integration-test/spring-boot-sni-integration-tests/build.gradle b/integration-test/spring-boot-sni-integration-tests/build.gradle index 9318080e804..0f8393f9b92 100644 --- a/integration-test/spring-boot-sni-integration-tests/build.gradle +++ b/integration-test/spring-boot-sni-integration-tests/build.gradle @@ -31,7 +31,6 @@ dependencies { app project(path: ":starter:spring-boot-starter", configuration: "mavenRepository") app project(path: ":starter:spring-boot-starter-actuator", configuration: "mavenRepository") app project(path: ":starter:spring-boot-starter-tomcat", configuration: "mavenRepository") - app project(path: ":starter:spring-boot-starter-undertow", configuration: "mavenRepository") app project(path: ":starter:spring-boot-starter-web", configuration: "mavenRepository") app project(path: ":starter:spring-boot-starter-webflux", configuration: "mavenRepository") app project(path: ":build-plugin:spring-boot-gradle-plugin", configuration: "mavenRepository") @@ -61,8 +60,7 @@ tasks.register("buildReactiveServerApps", GradleBuild) { startParameter.buildCacheEnabled = false tasks = [ "nettyServerApp", - "tomcatServerApp", - "undertowServerApp" + "tomcatServerApp" ] } @@ -76,8 +74,7 @@ tasks.register("buildServletServerApps", GradleBuild) { dir = layout.buildDirectory.dir("spring-boot-sni-servlet-app") startParameter.buildCacheEnabled = false tasks = [ - "tomcatServerApp", - "undertowServerApp" + "tomcatServerApp" ] } @@ -97,9 +94,7 @@ intTest { inputs.files( layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-netty-reactive.jar"), layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat-reactive.jar"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat-servlet.jar"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-undertow-reactive.jar"), - layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-undertow-servlet.jar") + layout.buildDirectory.file("spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-tomcat-servlet.jar") ) .withPropertyName("applicationArchives") .withPathSensitivity(PathSensitivity.RELATIVE) diff --git a/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-reactive-app/build.gradle b/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-reactive-app/build.gradle index 8d022ff083a..5e92e1a245d 100644 --- a/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-reactive-app/build.gradle +++ b/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-reactive-app/build.gradle @@ -42,9 +42,6 @@ configurations { tomcat { extendsFrom(app) } - undertow { - extendsFrom(app) - } } dependencies { @@ -58,10 +55,9 @@ dependencies { app("org.springframework.boot:spring-boot-webflux") netty("org.springframework.boot:spring-boot-starter-webflux") tomcat("org.springframework.boot:spring-boot-starter-tomcat") - undertow("org.springframework.boot:spring-boot-starter-undertow") } -["netty", "tomcat", "undertow"].each { webServer -> +["netty", "tomcat"].each { webServer -> def configurer = { task -> task.mainClass = "org.springframework.boot.sni.server.SniServerApplication" task.classpath = configurations.getByName(webServer) diff --git a/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-servlet-app/build.gradle b/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-servlet-app/build.gradle index df4fc7ccd23..67a0e190c09 100644 --- a/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-servlet-app/build.gradle +++ b/integration-test/spring-boot-sni-integration-tests/spring-boot-sni-servlet-app/build.gradle @@ -39,9 +39,6 @@ configurations { tomcat { extendsFrom(app) } - undertow { - extendsFrom(app) - } } dependencies { @@ -58,10 +55,9 @@ dependencies { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' } tomcat("org.springframework.boot:spring-boot-starter-tomcat") - undertow("org.springframework.boot:spring-boot-starter-undertow") } -["tomcat", "undertow"].each { webServer -> +["tomcat"].each { webServer -> def configurer = { task -> task.mainClass = "org.springframework.boot.sni.server.SniServerApplication" task.classpath = configurations.getByName(webServer) diff --git a/integration-test/spring-boot-sni-integration-tests/src/intTest/java/org/springframework/boot/sni/SniIntegrationTests.java b/integration-test/spring-boot-sni-integration-tests/src/intTest/java/org/springframework/boot/sni/SniIntegrationTests.java index 84ae7b18103..8448ef1acbc 100644 --- a/integration-test/spring-boot-sni-integration-tests/src/intTest/java/org/springframework/boot/sni/SniIntegrationTests.java +++ b/integration-test/spring-boot-sni-integration-tests/src/intTest/java/org/springframework/boot/sni/SniIntegrationTests.java @@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SniIntegrationTests { private static final Map SERVER_START_MESSAGES = Map.ofEntries(Map.entry("netty", "Netty started"), - Map.entry("tomcat", "Tomcat initialized"), Map.entry("undertow", "starting server: Undertow")); + Map.entry("tomcat", "Tomcat initialized")); public static final String PRIMARY_SERVER_NAME = "hello.example.com"; @@ -53,7 +53,7 @@ class SniIntegrationTests { private static final Network SHARED_NETWORK = Network.newNetwork(); @ParameterizedTest - @CsvSource({ "reactive,netty", "reactive,tomcat", "servlet,tomcat", "reactive,undertow", "servlet,undertow" }) + @CsvSource({ "reactive,netty", "reactive,tomcat", "servlet,tomcat" }) void home(String webStack, String server) { try (ApplicationContainer serverContainer = new ServerApplicationContainer(webStack, server)) { serverContainer.start(); diff --git a/module/spring-boot-autoconfigure-classic-modules/build.gradle b/module/spring-boot-autoconfigure-classic-modules/build.gradle index 981c8f1bf13..e960a5e6984 100644 --- a/module/spring-boot-autoconfigure-classic-modules/build.gradle +++ b/module/spring-boot-autoconfigure-classic-modules/build.gradle @@ -259,9 +259,6 @@ dependencies { api(project(":module:spring-boot-tx")) { transitive = false } - api(project(":module:spring-boot-undertow")) { - transitive = false - } api(project(":module:spring-boot-validation")) { transitive = false } diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java index 073d04200d3..01da8404428 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java @@ -24,7 +24,7 @@ import org.eclipse.jetty.http.HttpMethod; * HttpMethods} rather than just {@code GET}, {@code POST} and {@code HEAD}. By default * Jetty intentionally only * supports a limited set of HTTP methods for error pages, however, Spring Boot - * prefers Tomcat, Jetty and Undertow to all behave in the same way. + * prefers Tomcat and Jetty to all behave in the same way. * * @author Phillip Webb * @author Christoph Dreis diff --git a/module/spring-boot-servlet/build.gradle b/module/spring-boot-servlet/build.gradle index 88b4a5f9c24..f9118dc8c8e 100644 --- a/module/spring-boot-servlet/build.gradle +++ b/module/spring-boot-servlet/build.gradle @@ -38,7 +38,6 @@ dependencies { testImplementation(project(":module:spring-boot-jetty")) testImplementation(project(":module:spring-boot-tomcat")) testImplementation(project(":test-support:spring-boot-test-support")) - testImplementation(project(":module:spring-boot-undertow")) testImplementation("org.springframework:spring-webmvc") testRuntimeOnly("ch.qos.logback:logback-classic") diff --git a/module/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java b/module/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java index 4aa99d3b955..016c5fe312b 100644 --- a/module/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java +++ b/module/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java @@ -33,7 +33,6 @@ import org.springframework.boot.testsupport.classpath.ForkedClassPath; import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; @@ -104,8 +103,7 @@ class MultipartAutoConfigurationTests { static Stream webServerWithNoMultipartConfigurationArguments() { return Stream.of(Arguments.of("Jetty", WebServerWithNoMultipartJetty.class), - Arguments.of("Tomcat", WebServerWithNoMultipartTomcat.class), - Arguments.of("Undertow", WebServerWithNoMultipartUndertow.class)); + Arguments.of("Tomcat", WebServerWithNoMultipartTomcat.class)); } @ParameterizedTest(name = "{0}") @@ -121,18 +119,7 @@ class MultipartAutoConfigurationTests { static Stream webServerWithAutomatedMultipartConfigurationArguments() { return Stream.of(Arguments.of("Jetty", WebServerWithEverythingJetty.class), - Arguments.of("Tomcat", WebServerWithEverythingTomcat.class), - Arguments.of("Undertow", WebServerWithEverythingUndertow.class)); - } - - @Test - void webServerWithNonAbsoluteMultipartLocationUndertowConfiguration() { - this.context = new AnnotationConfigServletWebServerApplicationContext( - WebServerWithNonAbsolutePathUndertow.class, BaseConfiguration.class); - this.context.getBean(MultipartConfigElement.class); - verifyServletWorks(); - assertThat(this.context.getBean(StandardServletMultipartResolver.class)) - .isSameAs(this.context.getBean(DispatcherServlet.class).getMultipartResolver()); + Arguments.of("Tomcat", WebServerWithEverythingTomcat.class)); } @Test @@ -248,21 +235,6 @@ class MultipartAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - static class WebServerWithNoMultipartUndertow { - - @Bean - UndertowServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(); - } - - @Bean - WebController controller() { - return new WebController(); - } - - } - @Configuration(proxyBeanMethods = false) @Import({ TomcatServletWebServerAutoConfiguration.class, MultipartAutoConfiguration.class }) @EnableConfigurationProperties(MultipartProperties.class) @@ -338,48 +310,6 @@ class MultipartAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - @EnableWebMvc - static class WebServerWithEverythingUndertow { - - @Bean - MultipartConfigElement multipartConfigElement() { - return new MultipartConfigElement(""); - } - - @Bean - UndertowServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(); - } - - @Bean - WebController webController() { - return new WebController(); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebMvc - static class WebServerWithNonAbsolutePathUndertow { - - @Bean - MultipartConfigElement multipartConfigElement() { - return new MultipartConfigElement("test/not-absolute"); - } - - @Bean - UndertowServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(); - } - - @Bean - WebController webController() { - return new WebController(); - } - - } - @Configuration(proxyBeanMethods = false) static class WebServerWithCustomMultipartResolver { diff --git a/module/spring-boot-undertow/build.gradle b/module/spring-boot-undertow/build.gradle deleted file mode 100644 index 215a173d455..00000000000 --- a/module/spring-boot-undertow/build.gradle +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "java-library" - id "org.springframework.boot.auto-configuration" - id "org.springframework.boot.configuration-properties" - id "org.springframework.boot.deployed" - id "org.springframework.boot.optional-dependencies" -} - -description = "Spring Boot Undertow" - -dependencies { - api(project(":module:spring-boot-web-server")) - api("io.undertow:undertow-servlet") - - optional(project(":core:spring-boot-autoconfigure")) - optional(project(":module:spring-boot-actuator-autoconfigure")) - optional("io.undertow:undertow-websockets-jsr") - optional("org.springframework:spring-webflux") - - testImplementation(project(":core:spring-boot-test")) - testImplementation(project(":test-support:spring-boot-test-support")) - testImplementation(testFixtures(project(":core:spring-boot-autoconfigure"))) - testImplementation(testFixtures(project(":module:spring-boot-web-server"))) - testImplementation("org.apache.httpcomponents.client5:httpclient5") - testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper") - - testRuntimeOnly("ch.qos.logback:logback-classic") - testRuntimeOnly("io.projectreactor:reactor-test") - testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") - testRuntimeOnly("org.eclipse.jetty:jetty-client") - testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client") - testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") - testRuntimeOnly("org.springframework:spring-webmvc") -} - -test { - jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java deleted file mode 100644 index 2456b3e95bc..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import io.undertow.Undertow; -import io.undertow.server.HttpHandler; -import io.undertow.server.handlers.accesslog.AccessLogHandler; -import io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver; -import org.jspecify.annotations.Nullable; -import org.xnio.OptionMap; -import org.xnio.Options; -import org.xnio.Xnio; -import org.xnio.XnioWorker; - -/** - * An {@link HttpHandlerFactory} for an {@link AccessLogHandler}. - * - * @author Andy Wilkinson - */ -class AccessLogHttpHandlerFactory implements HttpHandlerFactory { - - private final File directory; - - private final @Nullable String pattern; - - private final @Nullable String prefix; - - private final @Nullable String suffix; - - private final boolean rotate; - - AccessLogHttpHandlerFactory(File directory, @Nullable String pattern, @Nullable String prefix, - @Nullable String suffix, boolean rotate) { - this.directory = directory; - this.pattern = pattern; - this.prefix = prefix; - this.suffix = suffix; - this.rotate = rotate; - } - - @Override - public HttpHandler getHandler(@Nullable HttpHandler next) { - try { - createAccessLogDirectoryIfNecessary(); - XnioWorker worker = createWorker(); - String baseName = (this.prefix != null) ? this.prefix : "access_log."; - String formatString = (this.pattern != null) ? this.pattern : "common"; - return new ClosableAccessLogHandler(next, worker, - new DefaultAccessLogReceiver(worker, this.directory, baseName, this.suffix, this.rotate), - formatString); - } - catch (IOException ex) { - throw new IllegalStateException("Failed to create AccessLogHandler", ex); - } - } - - private void createAccessLogDirectoryIfNecessary() { - if (!this.directory.isDirectory() && !this.directory.mkdirs()) { - throw new IllegalStateException("Failed to create access log directory '" + this.directory + "'"); - } - } - - private XnioWorker createWorker() throws IOException { - Xnio xnio = Xnio.getInstance(Undertow.class.getClassLoader()); - return xnio.createWorker(OptionMap.builder().set(Options.THREAD_DAEMON, true).getMap()); - } - - /** - * {@link Closeable} variant of {@link AccessLogHandler}. - */ - private static class ClosableAccessLogHandler extends AccessLogHandler implements Closeable { - - private final DefaultAccessLogReceiver accessLogReceiver; - - private final XnioWorker worker; - - ClosableAccessLogHandler(@Nullable HttpHandler next, XnioWorker worker, - DefaultAccessLogReceiver accessLogReceiver, String formatString) { - super(next, accessLogReceiver, formatString, Undertow.class.getClassLoader()); - this.worker = worker; - this.accessLogReceiver = accessLogReceiver; - } - - @Override - public void close() throws IOException { - try { - this.accessLogReceiver.close(); - this.worker.shutdown(); - this.worker.awaitTermination(30, TimeUnit.SECONDS); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java deleted file mode 100644 index 4feb1c30c72..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.util.ArrayList; -import java.util.List; - -import io.undertow.attribute.RequestHeaderAttribute; -import io.undertow.predicate.Predicate; -import io.undertow.predicate.Predicates; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; -import io.undertow.server.handlers.encoding.ContentEncodingRepository; -import io.undertow.server.handlers.encoding.EncodingHandler; -import io.undertow.server.handlers.encoding.GzipEncodingProvider; -import io.undertow.util.Headers; -import io.undertow.util.HttpString; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.web.server.Compression; -import org.springframework.http.HttpHeaders; -import org.springframework.util.InvalidMimeTypeException; -import org.springframework.util.MimeType; -import org.springframework.util.MimeTypeUtils; - -/** - * {@link HttpHandlerFactory} that adds a compression handler. - * - * @author Andy Wilkinson - * @author Phillip Webb - */ -class CompressionHttpHandlerFactory implements HttpHandlerFactory { - - private final Compression compression; - - CompressionHttpHandlerFactory(Compression compression) { - this.compression = compression; - } - - @Override - public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) { - if (!this.compression.getEnabled()) { - return next; - } - ContentEncodingRepository repository = new ContentEncodingRepository(); - repository.addEncodingHandler("gzip", new GzipEncodingProvider(), 50, - Predicates.and(getCompressionPredicates(this.compression))); - return new EncodingHandler(repository).setNext(next); - } - - private static Predicate[] getCompressionPredicates(Compression compression) { - List predicates = new ArrayList<>(); - predicates.add(new MaxSizePredicate((int) compression.getMinResponseSize().toBytes())); - predicates.add(new CompressibleMimeTypePredicate(compression.getMimeTypes())); - if (compression.getExcludedUserAgents() != null) { - for (String agent : compression.getExcludedUserAgents()) { - RequestHeaderAttribute agentHeader = new RequestHeaderAttribute(new HttpString(HttpHeaders.USER_AGENT)); - predicates.add(Predicates.not(Predicates.regex(agentHeader, agent))); - } - } - return predicates.toArray(new Predicate[0]); - } - - /** - * Predicate used to match specific mime types. - */ - private static class CompressibleMimeTypePredicate implements Predicate { - - private final List mimeTypes; - - CompressibleMimeTypePredicate(String[] mimeTypes) { - this.mimeTypes = new ArrayList<>(mimeTypes.length); - for (String mimeTypeString : mimeTypes) { - this.mimeTypes.add(MimeTypeUtils.parseMimeType(mimeTypeString)); - } - } - - @Override - public boolean resolve(HttpServerExchange value) { - String contentType = value.getResponseHeaders().getFirst(HttpHeaders.CONTENT_TYPE); - if (contentType != null) { - try { - MimeType parsed = MimeTypeUtils.parseMimeType(contentType); - for (MimeType mimeType : this.mimeTypes) { - if (mimeType.isCompatibleWith(parsed)) { - return true; - } - } - } - catch (InvalidMimeTypeException ex) { - return false; - } - } - return false; - } - - } - - /** - * Predicate that returns true if the Content-Size of a request is above a given value - * or is missing. - */ - private static class MaxSizePredicate implements Predicate { - - private final Predicate maxContentSize; - - MaxSizePredicate(int size) { - this.maxContentSize = Predicates.requestLargerThan(size); - } - - @Override - public boolean resolve(HttpServerExchange value) { - if (value.getResponseHeaders().contains(Headers.CONTENT_LENGTH)) { - return this.maxContentSize.resolve(value); - } - return true; - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java deleted file mode 100644 index 0b83b98d0ea..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.io.File; -import java.util.Collection; - -import io.undertow.Undertow.Builder; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.web.server.ConfigurableWebServerFactory; - -/** - * {@link ConfigurableWebServerFactory} for Undertow-specific features. - * - * @author Brian Clozel - * @since 4.0.0 - */ -public interface ConfigurableUndertowWebServerFactory extends ConfigurableWebServerFactory { - - /** - * Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow - * {@link Builder}. Calling this method will replace any existing customizers. - * @param customizers the customizers to set - * @since 4.0.0 - */ - void setBuilderCustomizers(Collection customizers); - - /** - * Add {@link UndertowBuilderCustomizer}s that should be used to customize the - * Undertow {@link Builder}. - * @param customizers the customizers to add - */ - void addBuilderCustomizers(UndertowBuilderCustomizer... customizers); - - /** - * Set the buffer size. - * @param bufferSize buffer size - */ - void setBufferSize(@Nullable Integer bufferSize); - - /** - * Set the number of IO Threads. - * @param ioThreads number of IO Threads - */ - void setIoThreads(@Nullable Integer ioThreads); - - /** - * Set the number of Worker Threads. - * @param workerThreads number of Worker Threads - */ - void setWorkerThreads(@Nullable Integer workerThreads); - - /** - * Set whether direct buffers should be used. - * @param useDirectBuffers whether direct buffers should be used - */ - void setUseDirectBuffers(@Nullable Boolean useDirectBuffers); - - /** - * Set the access log directory. - * @param accessLogDirectory access log directory - */ - void setAccessLogDirectory(@Nullable File accessLogDirectory); - - /** - * Set the access log pattern. - * @param accessLogPattern access log pattern - */ - void setAccessLogPattern(@Nullable String accessLogPattern); - - /** - * Set the access log prefix. - * @param accessLogPrefix log prefix - */ - void setAccessLogPrefix(@Nullable String accessLogPrefix); - - /** - * Set the access log suffix. - * @param accessLogSuffix access log suffix - */ - void setAccessLogSuffix(@Nullable String accessLogSuffix); - - /** - * Set whether access logs are enabled. - * @param accessLogEnabled whether access logs are enabled - */ - void setAccessLogEnabled(boolean accessLogEnabled); - - /** - * Set whether access logs rotation is enabled. - * @param accessLogRotate whether access logs rotation is enabled - */ - void setAccessLogRotate(boolean accessLogRotate); - - /** - * Set if x-forward-* headers should be processed. - * @param useForwardHeaders if x-forward headers should be used - */ - void setUseForwardHeaders(boolean useForwardHeaders); - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java deleted file mode 100644 index 225757b7829..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.io.Closeable; - -import io.undertow.server.HttpHandler; -import io.undertow.server.handlers.GracefulShutdownHandler; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.undertow.servlet.UndertowServletWebServer; - -/** - * Factory used by {@link UndertowServletWebServer} to add {@link HttpHandler - * HttpHandlers}. Instances returned from this factory may optionally implement the - * following interfaces: - *
    - *
  • {@link Closeable} - if they wish to be closed just before server stops.
  • - *
  • {@link GracefulShutdownHandler} - if they wish to manage graceful shutdown.
  • - *
- * - * @author Phillip Webb - * @since 4.0.0 - */ -@FunctionalInterface -public interface HttpHandlerFactory { - - /** - * Create the {@link HttpHandler} instance that should be added. - * @param next the next handler in the chain - * @return the new HTTP handler instance - */ - @Nullable HttpHandler getHandler(@Nullable HttpHandler next); - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java deleted file mode 100644 index 8f0f402d247..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.net.InetAddress; -import java.util.Map; - -import javax.net.ssl.SSLContext; - -import io.undertow.Undertow; -import io.undertow.protocols.ssl.SNIContextMatcher; -import io.undertow.protocols.ssl.SNISSLContext; -import org.jspecify.annotations.Nullable; -import org.xnio.Options; -import org.xnio.Sequence; -import org.xnio.SslClientAuthMode; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslOptions; -import org.springframework.boot.web.server.Ssl.ClientAuth; - -/** - * {@link UndertowBuilderCustomizer} that configures SSL on the given builder instance. - * - * @author Brian Clozel - * @author Raheela Aslam - * @author Cyril Dangerville - * @author Scott Frederick - */ -class SslBuilderCustomizer implements UndertowBuilderCustomizer { - - private final int port; - - private final @Nullable InetAddress address; - - private final @Nullable ClientAuth clientAuth; - - private final SslBundle sslBundle; - - private final Map serverNameSslBundles; - - SslBuilderCustomizer(int port, @Nullable InetAddress address, @Nullable ClientAuth clientAuth, SslBundle sslBundle, - Map serverNameSslBundles) { - this.port = port; - this.address = address; - this.clientAuth = clientAuth; - this.sslBundle = sslBundle; - this.serverNameSslBundles = serverNameSslBundles; - } - - @Override - public void customize(Undertow.Builder builder) { - SslOptions options = this.sslBundle.getOptions(); - builder.addHttpsListener(this.port, getListenAddress(), createSslContext()); - builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, ClientAuth.map(this.clientAuth, - SslClientAuthMode.NOT_REQUESTED, SslClientAuthMode.REQUESTED, SslClientAuthMode.REQUIRED)); - if (options.getEnabledProtocols() != null) { - builder.setSocketOption(Options.SSL_ENABLED_PROTOCOLS, Sequence.of(options.getEnabledProtocols())); - } - if (options.getCiphers() != null) { - builder.setSocketOption(Options.SSL_ENABLED_CIPHER_SUITES, Sequence.of(options.getCiphers())); - } - } - - private SSLContext createSslContext() { - SNIContextMatcher.Builder builder = new SNIContextMatcher.Builder(); - builder.setDefaultContext(this.sslBundle.createSslContext()); - this.serverNameSslBundles - .forEach((serverName, sslBundle) -> builder.addMatch(serverName, sslBundle.createSslContext())); - return new SNISSLContext(builder.build()); - } - - private String getListenAddress() { - if (this.address == null) { - return "0.0.0.0"; - } - return this.address.getHostAddress(); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java deleted file mode 100644 index e79ae7a4acd..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import io.undertow.Undertow.Builder; - -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; - -/** - * Callback interface that can be used to customize an Undertow {@link Builder}. - * - * @author Andy Wilkinson - * @since 4.0.0 - * @see UndertowServletWebServerFactory - */ -@FunctionalInterface -public interface UndertowBuilderCustomizer { - - /** - * Customize the builder. - * @param builder the {@code Builder} to customize - */ - void customize(Builder builder); - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java deleted file mode 100644 index 58f6c6634d8..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.io.Closeable; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import io.undertow.Undertow; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; -import io.undertow.server.handlers.GracefulShutdownHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jspecify.annotations.Nullable; -import org.xnio.channels.BoundChannel; - -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.boot.web.server.GracefulShutdownCallback; -import org.springframework.boot.web.server.GracefulShutdownResult; -import org.springframework.boot.web.server.PortInUseException; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.WebServerException; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * {@link WebServer} that can be used to control an Undertow web server. Usually this - * class should be created using a {@link ConfigurableUndertowWebServerFactory} and not - * directly. - * - * @author Ivan Sopov - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Christoph Dreis - * @author Brian Clozel - * @since 4.0.0 - */ -public class UndertowWebServer implements WebServer { - - private static final Log logger = LogFactory.getLog(UndertowWebServer.class); - - private final AtomicReference<@Nullable GracefulShutdownCallback> gracefulShutdownCallback = new AtomicReference<>(); - - private final Object monitor = new Object(); - - private final Undertow.Builder builder; - - private final Iterable httpHandlerFactories; - - private final boolean autoStart; - - private @Nullable Undertow undertow; - - private volatile boolean started = false; - - private volatile @Nullable GracefulShutdownHandler gracefulShutdown; - - private volatile @Nullable List closeables; - - /** - * Create a new {@link UndertowWebServer} instance. - * @param builder the builder - * @param autoStart if the server should be started - */ - public UndertowWebServer(Undertow.Builder builder, boolean autoStart) { - this(builder, Collections.singleton(new CloseableHttpHandlerFactory(null)), autoStart); - } - - /** - * Create a new {@link UndertowWebServer} instance. - * @param builder the builder - * @param httpHandlerFactories the handler factories - * @param autoStart if the server should be started - * @since 4.0.0 - */ - public UndertowWebServer(Undertow.Builder builder, Iterable httpHandlerFactories, - boolean autoStart) { - this.builder = builder; - this.httpHandlerFactories = httpHandlerFactories; - this.autoStart = autoStart; - } - - @Override - public void start() throws WebServerException { - synchronized (this.monitor) { - if (this.started) { - return; - } - try { - if (!this.autoStart) { - return; - } - if (this.undertow == null) { - this.undertow = createUndertowServer(); - } - this.undertow.start(); - this.started = true; - String message = getStartedLogMessage(); - logger.info(message); - } - catch (Exception ex) { - try { - PortInUseException.ifPortBindingException(ex, (bindException) -> { - List failedPorts = getConfiguredPorts(); - failedPorts.removeAll(getActualPorts()); - if (failedPorts.size() == 1) { - throw new PortInUseException(failedPorts.get(0).getNumber()); - } - }); - throw new WebServerException("Unable to start embedded Undertow", ex); - } - finally { - destroySilently(); - } - } - } - } - - private void destroySilently() { - try { - if (this.undertow != null) { - this.undertow.stop(); - Assert.state(this.closeables != null, "'closeables' must not be null"); - this.closeables.forEach(this::closeSilently); - } - } - catch (Exception ex) { - // Ignore - } - } - - private void closeSilently(Closeable closeable) { - try { - closeable.close(); - } - catch (Exception ex) { - // Ignore - } - } - - private Undertow createUndertowServer() { - this.closeables = new ArrayList<>(); - this.gracefulShutdown = null; - HttpHandler handler = createHttpHandler(); - this.builder.setHandler(handler); - return this.builder.build(); - } - - protected @Nullable HttpHandler createHttpHandler() { - HttpHandler handler = null; - for (HttpHandlerFactory factory : this.httpHandlerFactories) { - handler = factory.getHandler(handler); - if (handler instanceof Closeable closeable) { - Assert.state(this.closeables != null, "'closeables' must not be null"); - this.closeables.add(closeable); - } - if (handler instanceof GracefulShutdownHandler shutdownHandler) { - Assert.state(this.gracefulShutdown == null, "Only a single GracefulShutdownHandler can be defined"); - this.gracefulShutdown = shutdownHandler; - } - } - return handler; - } - - private String getPortsDescription() { - StringBuilder description = new StringBuilder(); - List ports = getActualPorts(); - description.append("port"); - if (ports.size() != 1) { - description.append("s"); - } - description.append(" "); - if (!ports.isEmpty()) { - description.append(StringUtils.collectionToDelimitedString(ports, ", ")); - } - else { - description.append("unknown"); - } - return description.toString(); - } - - private List getActualPorts() { - List ports = new ArrayList<>(); - try { - if (!this.autoStart) { - ports.add(new Port(-1, "unknown")); - } - else { - for (BoundChannel channel : extractChannels()) { - ports.add(getPortFromChannel(channel)); - } - } - } - catch (Exception ex) { - // Continue - } - return ports; - } - - @SuppressWarnings("unchecked") - private List extractChannels() { - Field channelsField = ReflectionUtils.findField(Undertow.class, "channels"); - Assert.state(channelsField != null, "'channelsField' must not be null"); - ReflectionUtils.makeAccessible(channelsField); - List channels = (List) ReflectionUtils.getField(channelsField, this.undertow); - Assert.state(channels != null, "'channels' must not be null"); - return channels; - } - - private UndertowWebServer.@Nullable Port getPortFromChannel(BoundChannel channel) { - SocketAddress socketAddress = channel.getLocalAddress(); - if (socketAddress instanceof InetSocketAddress inetSocketAddress) { - Field sslField = ReflectionUtils.findField(channel.getClass(), "ssl"); - String protocol = (sslField != null) ? "https" : "http"; - return new UndertowWebServer.Port(inetSocketAddress.getPort(), protocol); - } - return null; - } - - private List getConfiguredPorts() { - List ports = new ArrayList<>(); - for (Object listener : extractListeners()) { - try { - Port port = getPortFromListener(listener); - if (port.getNumber() != 0) { - ports.add(port); - } - } - catch (Exception ex) { - // Continue - } - } - return ports; - } - - @SuppressWarnings("unchecked") - private List extractListeners() { - Field listenersField = ReflectionUtils.findField(Undertow.class, "listeners"); - Assert.state(listenersField != null, "'listenersField' must not be null"); - ReflectionUtils.makeAccessible(listenersField); - List listeners = (List) ReflectionUtils.getField(listenersField, this.undertow); - Assert.state(listeners != null, "'listeners' must not be null"); - return listeners; - } - - private UndertowWebServer.Port getPortFromListener(Object listener) { - Field typeField = ReflectionUtils.findField(listener.getClass(), "type"); - Assert.state(typeField != null, "'typeField' must not be null"); - String protocol = getProtocol(listener, typeField); - Field portField = ReflectionUtils.findField(listener.getClass(), "port"); - Assert.state(portField != null, "'portField' must not be null"); - int port = getPort(listener, portField); - return new UndertowWebServer.Port(port, protocol); - } - - private static Integer getPort(Object listener, Field portField) { - ReflectionUtils.makeAccessible(portField); - Integer value = (Integer) ReflectionUtils.getField(portField, listener); - Assert.state(value != null, "'value' must not be null"); - return value; - } - - private String getProtocol(Object listener, Field typeField) { - ReflectionUtils.makeAccessible(typeField); - Object value = ReflectionUtils.getField(typeField, listener); - Assert.state(value != null, "'value' must not be null"); - return value.toString(); - } - - @Override - public void stop() throws WebServerException { - synchronized (this.monitor) { - if (!this.started) { - return; - } - this.started = false; - if (this.gracefulShutdown != null) { - notifyGracefulCallback(false); - } - try { - if (this.undertow != null) { - this.undertow.stop(); - Assert.state(this.closeables != null, "'closeables' must not be null"); - for (Closeable closeable : this.closeables) { - closeable.close(); - } - } - } - catch (Exception ex) { - throw new WebServerException("Unable to stop Undertow", ex); - } - } - } - - @Override - public int getPort() { - List ports = getActualPorts(); - if (ports.isEmpty()) { - return -1; - } - return ports.get(0).getNumber(); - } - - /** - * Returns the {@link Undertow Undertow server}. Returns {@code null} until the server - * has been started. - * @return the Undertow server or {@code null} if the server hasn't been started yet - * @since 4.0.0 - */ - public @Nullable Undertow getUndertow() { - return this.undertow; - } - - /** - * Initiates a graceful shutdown of the Undertow web server. Handling of new requests - * is prevented and the given {@code callback} is invoked at the end of the attempt. - * The attempt can be explicitly ended by invoking {@link #stop}. - *

- * Once shutdown has been initiated Undertow will return an {@code HTTP 503} response - * for any new or existing connections. - */ - @Override - public void shutDownGracefully(GracefulShutdownCallback callback) { - if (this.gracefulShutdown == null) { - callback.shutdownComplete(GracefulShutdownResult.IMMEDIATE); - return; - } - logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); - this.gracefulShutdownCallback.set(callback); - this.gracefulShutdown.shutdown(); - this.gracefulShutdown.addShutdownListener(this::notifyGracefulCallback); - } - - private void notifyGracefulCallback(boolean success) { - GracefulShutdownCallback callback = this.gracefulShutdownCallback.getAndSet(null); - if (callback != null) { - if (success) { - logger.info("Graceful shutdown complete"); - callback.shutdownComplete(GracefulShutdownResult.IDLE); - } - else { - logger.info("Graceful shutdown aborted with one or more requests still active"); - callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); - } - } - } - - protected String getStartedLogMessage() { - return "Undertow started on " + getPortsDescription(); - } - - /** - * An active Undertow port. - */ - private static final class Port { - - private final int number; - - private final String protocol; - - private Port(int number, String protocol) { - this.number = number; - this.protocol = protocol; - } - - int getNumber() { - return this.number; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - UndertowWebServer.Port other = (UndertowWebServer.Port) obj; - return this.number == other.number; - } - - @Override - public int hashCode() { - return this.number; - } - - @Override - public String toString() { - return this.number + " (" + this.protocol + ")"; - } - - } - - /** - * {@link HttpHandlerFactory} to wrap a closable. - */ - private static final class CloseableHttpHandlerFactory implements HttpHandlerFactory { - - private final @Nullable Closeable closeable; - - private CloseableHttpHandlerFactory(@Nullable Closeable closeable) { - this.closeable = closeable; - } - - @Override - public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) { - Closeable closeable = this.closeable; - if (closeable == null) { - return next; - } - return new CloseableHttpHandler() { - - @Override - public void handleRequest(HttpServerExchange exchange) throws Exception { - if (next != null) { - next.handleRequest(exchange); - } - } - - @Override - public void close() throws IOException { - closeable.close(); - } - - }; - } - - } - - /** - * {@link Closeable} {@link HttpHandler}. - */ - private interface CloseableHttpHandler extends HttpHandler, Closeable { - - } - - /** - * {@link RuntimeHintsRegistrar} that allows Undertow's configured and actual ports to - * be retrieved at runtime in a native image. - */ - static class UndertowWebServerRuntimeHints implements RuntimeHintsRegistrar { - - @Override - public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { - hints.reflection() - .registerTypeIfPresent(classLoader, "io.undertow.Undertow", - (hint) -> hint.withField("listeners").withField("channels")); - hints.reflection() - .registerTypeIfPresent(classLoader, "io.undertow.Undertow$ListenerConfig", - (hint) -> hint.withField("type").withField("port")); - hints.reflection() - .registerTypeIfPresent(classLoader, "io.undertow.protocols.ssl.UndertowAcceptingSslChannel", - (hint) -> hint.withField("ssl")); - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java deleted file mode 100644 index d1dba06ec39..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.io.File; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - -import io.undertow.Handlers; -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import io.undertow.UndertowOptions; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.boot.web.server.Compression; -import org.springframework.boot.web.server.Http2; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.Ssl; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Base class for factories that produce an {@link UndertowWebServer}. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -public abstract class UndertowWebServerFactory extends AbstractConfigurableWebServerFactory - implements ConfigurableUndertowWebServerFactory { - - private Set builderCustomizers = new LinkedHashSet<>(); - - private @Nullable Integer bufferSize; - - private @Nullable Integer ioThreads; - - private @Nullable Integer workerThreads; - - private @Nullable Boolean directBuffers; - - private @Nullable File accessLogDirectory; - - private @Nullable String accessLogPattern; - - private @Nullable String accessLogPrefix; - - private @Nullable String accessLogSuffix; - - private boolean accessLogEnabled; - - private boolean accessLogRotate = true; - - private boolean useForwardHeaders; - - protected UndertowWebServerFactory() { - } - - protected UndertowWebServerFactory(int port) { - super(port); - } - - public Collection getBuilderCustomizers() { - return this.builderCustomizers; - } - - @Override - public void setBuilderCustomizers(Collection customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.builderCustomizers = new LinkedHashSet<>(customizers); - } - - @Override - public void addBuilderCustomizers(UndertowBuilderCustomizer... customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.builderCustomizers.addAll(Arrays.asList(customizers)); - } - - @Override - public void setBufferSize(@Nullable Integer bufferSize) { - this.bufferSize = bufferSize; - } - - @Override - public void setIoThreads(@Nullable Integer ioThreads) { - this.ioThreads = ioThreads; - } - - @Override - public void setWorkerThreads(@Nullable Integer workerThreads) { - this.workerThreads = workerThreads; - } - - @Override - public void setUseDirectBuffers(@Nullable Boolean directBuffers) { - this.directBuffers = directBuffers; - } - - @Override - public void setAccessLogDirectory(@Nullable File accessLogDirectory) { - this.accessLogDirectory = accessLogDirectory; - } - - @Override - public void setAccessLogPattern(@Nullable String accessLogPattern) { - this.accessLogPattern = accessLogPattern; - } - - @Override - public void setAccessLogPrefix(@Nullable String accessLogPrefix) { - this.accessLogPrefix = accessLogPrefix; - } - - public @Nullable String getAccessLogPrefix() { - return this.accessLogPrefix; - } - - @Override - public void setAccessLogSuffix(@Nullable String accessLogSuffix) { - this.accessLogSuffix = accessLogSuffix; - } - - @Override - public void setAccessLogEnabled(boolean accessLogEnabled) { - this.accessLogEnabled = accessLogEnabled; - } - - public boolean isAccessLogEnabled() { - return this.accessLogEnabled; - } - - @Override - public void setAccessLogRotate(boolean accessLogRotate) { - this.accessLogRotate = accessLogRotate; - } - - @Override - public void setUseForwardHeaders(boolean useForwardHeaders) { - this.useForwardHeaders = useForwardHeaders; - } - - public boolean isUseForwardHeaders() { - return this.useForwardHeaders; - } - - public Builder createBuilder(AbstractConfigurableWebServerFactory factory, Supplier sslBundleSupplier, - Supplier> serverNameSslBundlesSupplier) { - InetAddress address = factory.getAddress(); - int port = factory.getPort(); - Builder builder = Undertow.builder(); - if (this.bufferSize != null) { - builder.setBufferSize(this.bufferSize); - } - if (this.ioThreads != null) { - builder.setIoThreads(this.ioThreads); - } - if (this.workerThreads != null) { - builder.setWorkerThreads(this.workerThreads); - } - if (this.directBuffers != null) { - builder.setDirectBuffers(this.directBuffers); - } - Http2 http2 = factory.getHttp2(); - if (http2 != null) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, http2.isEnabled()); - } - Ssl ssl = factory.getSsl(); - if (Ssl.isEnabled(ssl)) { - new SslBuilderCustomizer(factory.getPort(), address, ssl.getClientAuth(), sslBundleSupplier.get(), - serverNameSslBundlesSupplier.get()) - .customize(builder); - } - else { - builder.addHttpListener(port, (address != null) ? address.getHostAddress() : "0.0.0.0"); - } - builder.setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 0); - for (UndertowBuilderCustomizer customizer : this.builderCustomizers) { - customizer.customize(builder); - } - return builder; - } - - public List createHttpHandlerFactories(AbstractConfigurableWebServerFactory webServerFactory, - HttpHandlerFactory... initialHttpHandlerFactories) { - List factories = createHttpHandlerFactories(webServerFactory.getCompression(), - this.useForwardHeaders, webServerFactory.getServerHeader(), webServerFactory.getShutdown(), - initialHttpHandlerFactories); - if (isAccessLogEnabled()) { - Assert.state(this.accessLogDirectory != null, "Access log directory is not set"); - factories.add(new AccessLogHttpHandlerFactory(this.accessLogDirectory, this.accessLogPattern, - this.accessLogPrefix, this.accessLogSuffix, this.accessLogRotate)); - } - return factories; - } - - static List createHttpHandlerFactories(@Nullable Compression compression, - boolean useForwardHeaders, @Nullable String serverHeader, Shutdown shutdown, - HttpHandlerFactory... initialHttpHandlerFactories) { - List factories = new ArrayList<>(Arrays.asList(initialHttpHandlerFactories)); - if (compression != null && compression.getEnabled()) { - factories.add(new CompressionHttpHandlerFactory(compression)); - } - if (useForwardHeaders) { - factories.add(Handlers::proxyPeerAddress); - } - if (StringUtils.hasText(serverHeader)) { - factories.add((next) -> Handlers.header(next, "Server", serverHeader)); - } - if (shutdown == Shutdown.GRACEFUL) { - factories.add(Handlers::gracefulShutdown); - } - return factories; - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java deleted file mode 100644 index 84d467c5635..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure; - -import java.io.File; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.LinkedHashMap; -import java.util.Map; - -import io.undertow.UndertowOptions; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.unit.DataSize; - -/** - * Undertow server properties. - * - * @author Dave Syer - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Ivan Sopov - * @author Marcos Barbero - * @author Eddú Meléndez - * @author Quinten De Swaef - * @author Venil Noronha - * @author Aurélien Leboulanger - * @author Brian Clozel - * @author Olivier Lamy - * @author Chentao Qu - * @author Artsiom Yudovin - * @author Andrew McGhie - * @author Rafiullah Hamedy - * @author Dirk Deyne - * @author HaiTao Zhang - * @author Victor Mandujano - * @author Chris Bono - * @author Parviz Rozikov - * @author Florian Storz - * @author Michael Weidmann - * @author Lasse Wulff - * @since 4.0.0 - */ -@ConfigurationProperties("server.undertow") -public class UndertowServerProperties { - - /** - * Maximum size of the HTTP post content. When the value is -1, the default, the size - * is unlimited. - */ - private DataSize maxHttpPostSize = DataSize.ofBytes(-1); - - /** - * Size of each buffer. The default is derived from the maximum amount of memory that - * is available to the JVM. - */ - private @Nullable DataSize bufferSize; - - /** - * Whether to allocate buffers outside the Java heap. The default is derived from the - * maximum amount of memory that is available to the JVM. - */ - private @Nullable Boolean directBuffers; - - /** - * Whether servlet filters should be initialized on startup. - */ - private boolean eagerFilterInit = true; - - /** - * Maximum number of query or path parameters that are allowed. This limit exists to - * prevent hash collision based DOS attacks. - */ - private int maxParameters = UndertowOptions.DEFAULT_MAX_PARAMETERS; - - /** - * Maximum number of headers that are allowed. This limit exists to prevent hash - * collision based DOS attacks. - */ - private int maxHeaders = UndertowOptions.DEFAULT_MAX_HEADERS; - - /** - * Maximum number of cookies that are allowed. This limit exists to prevent hash - * collision based DOS attacks. - */ - private int maxCookies = 200; - - /** - * Whether encoded slash characters (%2F) should be decoded. Decoding can cause - * security problems if a front-end proxy does not perform the same decoding. Only - * enable this if you have a legacy application that requires it. When set, - * server.undertow.allow-encoded-slash has no effect. - */ - private @Nullable Boolean decodeSlash; - - /** - * Whether the URL should be decoded. When disabled, percent-encoded characters in the - * URL will be left as-is. - */ - private boolean decodeUrl = true; - - /** - * Charset used to decode URLs. - */ - private Charset urlCharset = StandardCharsets.UTF_8; - - /** - * Whether the 'Connection: keep-alive' header should be added to all responses, even - * if not required by the HTTP specification. - */ - private boolean alwaysSetKeepAlive = true; - - /** - * Amount of time a connection can sit idle without processing a request, before it is - * closed by the server. - */ - private @Nullable Duration noRequestTimeout; - - /** - * Whether to preserve the path of a request when it is forwarded. - */ - private boolean preservePathOnForward = false; - - private final Accesslog accesslog = new Accesslog(); - - /** - * Thread related configuration. - */ - private final Threads threads = new Threads(); - - private final Options options = new Options(); - - public DataSize getMaxHttpPostSize() { - return this.maxHttpPostSize; - } - - public void setMaxHttpPostSize(DataSize maxHttpPostSize) { - this.maxHttpPostSize = maxHttpPostSize; - } - - public @Nullable DataSize getBufferSize() { - return this.bufferSize; - } - - public void setBufferSize(@Nullable DataSize bufferSize) { - this.bufferSize = bufferSize; - } - - public @Nullable Boolean getDirectBuffers() { - return this.directBuffers; - } - - public void setDirectBuffers(@Nullable Boolean directBuffers) { - this.directBuffers = directBuffers; - } - - public boolean isEagerFilterInit() { - return this.eagerFilterInit; - } - - public void setEagerFilterInit(boolean eagerFilterInit) { - this.eagerFilterInit = eagerFilterInit; - } - - public int getMaxParameters() { - return this.maxParameters; - } - - public void setMaxParameters(Integer maxParameters) { - this.maxParameters = maxParameters; - } - - public int getMaxHeaders() { - return this.maxHeaders; - } - - public void setMaxHeaders(int maxHeaders) { - this.maxHeaders = maxHeaders; - } - - public Integer getMaxCookies() { - return this.maxCookies; - } - - public void setMaxCookies(Integer maxCookies) { - this.maxCookies = maxCookies; - } - - public @Nullable Boolean getDecodeSlash() { - return this.decodeSlash; - } - - public void setDecodeSlash(@Nullable Boolean decodeSlash) { - this.decodeSlash = decodeSlash; - } - - public boolean isDecodeUrl() { - return this.decodeUrl; - } - - public void setDecodeUrl(Boolean decodeUrl) { - this.decodeUrl = decodeUrl; - } - - public Charset getUrlCharset() { - return this.urlCharset; - } - - public void setUrlCharset(Charset urlCharset) { - this.urlCharset = urlCharset; - } - - public boolean isAlwaysSetKeepAlive() { - return this.alwaysSetKeepAlive; - } - - public void setAlwaysSetKeepAlive(boolean alwaysSetKeepAlive) { - this.alwaysSetKeepAlive = alwaysSetKeepAlive; - } - - public @Nullable Duration getNoRequestTimeout() { - return this.noRequestTimeout; - } - - public void setNoRequestTimeout(@Nullable Duration noRequestTimeout) { - this.noRequestTimeout = noRequestTimeout; - } - - public boolean isPreservePathOnForward() { - return this.preservePathOnForward; - } - - public void setPreservePathOnForward(boolean preservePathOnForward) { - this.preservePathOnForward = preservePathOnForward; - } - - public UndertowServerProperties.Accesslog getAccesslog() { - return this.accesslog; - } - - public UndertowServerProperties.Threads getThreads() { - return this.threads; - } - - public UndertowServerProperties.Options getOptions() { - return this.options; - } - - /** - * Undertow access log properties. - */ - public static class Accesslog { - - /** - * Whether to enable the access log. - */ - private boolean enabled = false; - - /** - * Format pattern for access logs. - */ - private String pattern = "common"; - - /** - * Log file name prefix. - */ - protected String prefix = "access_log."; - - /** - * Log file name suffix. - */ - private String suffix = "log"; - - /** - * Undertow access log directory. - */ - private File dir = new File("logs"); - - /** - * Whether to enable access log rotation. - */ - private boolean rotate = true; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getPattern() { - return this.pattern; - } - - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return this.suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public File getDir() { - return this.dir; - } - - public void setDir(File dir) { - this.dir = dir; - } - - public boolean isRotate() { - return this.rotate; - } - - public void setRotate(boolean rotate) { - this.rotate = rotate; - } - - } - - /** - * Undertow thread properties. - */ - public static class Threads { - - /** - * Number of I/O threads to create for the worker. The default is derived from the - * number of available processors. - */ - private @Nullable Integer io; - - /** - * Number of worker threads. The default is 8 times the number of I/O threads. - */ - private @Nullable Integer worker; - - public @Nullable Integer getIo() { - return this.io; - } - - public void setIo(@Nullable Integer io) { - this.io = io; - } - - public @Nullable Integer getWorker() { - return this.worker; - } - - public void setWorker(@Nullable Integer worker) { - this.worker = worker; - } - - } - - public static class Options { - - /** - * Socket options as defined in org.xnio.Options. - */ - private final Map socket = new LinkedHashMap<>(); - - /** - * Server options as defined in io.undertow.UndertowOptions. - */ - private final Map server = new LinkedHashMap<>(); - - public Map getServer() { - return this.server; - } - - public Map getSocket() { - return this.socket; - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java deleted file mode 100644 index 140ff0f6ead..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; -import org.springframework.boot.web.server.autoconfigure.ServerProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * {@link Configuration Configuration} for an Undertow-based reactive or servlet web - * server. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -@ConditionalOnNotWarDeployment -@Configuration(proxyBeanMethods = false) -public class UndertowWebServerConfiguration { - - @Bean - UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties, UndertowServerProperties undertowProperties) { - return new UndertowWebServerFactoryCustomizer(environment, serverProperties, undertowProperties); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java deleted file mode 100644 index d05fa0b6ca3..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure; - -import java.lang.reflect.Modifier; -import java.nio.charset.Charset; -import java.time.Duration; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; - -import io.undertow.UndertowOptions; -import org.xnio.Option; -import org.xnio.Options; - -import org.springframework.boot.cloud.CloudPlatform; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; -import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties.Accesslog; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.server.autoconfigure.ServerProperties; -import org.springframework.core.Ordered; -import org.springframework.core.env.Environment; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.unit.DataSize; - -/** - * Customization for Undertow-specific features common for both Servlet and Reactive - * servers. - * - * @author Brian Clozel - * @author Yulin Qin - * @author Stephane Nicoll - * @author Phillip Webb - * @author Arstiom Yudovin - * @author Rafiullah Hamedy - * @author HaiTao Zhang - * @since 4.0.0 - */ -public class UndertowWebServerFactoryCustomizer - implements WebServerFactoryCustomizer, Ordered { - - private final Environment environment; - - private final ServerProperties serverProperties; - - private final UndertowServerProperties undertowProperties; - - public UndertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties, - UndertowServerProperties undertowProperties) { - this.environment = environment; - this.serverProperties = serverProperties; - this.undertowProperties = undertowProperties; - } - - @Override - public int getOrder() { - return 0; - } - - @Override - public void customize(ConfigurableUndertowWebServerFactory factory) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - ServerOptions options = new ServerOptions(factory); - map.from(this.serverProperties::getMaxHttpRequestHeaderSize) - .asInt(DataSize::toBytes) - .when(this::isPositive) - .to(options.option(UndertowOptions.MAX_HEADER_SIZE)); - mapUndertowProperties(factory, options); - mapAccessLogProperties(factory); - map.from(this::getOrDeduceUseForwardHeaders).to(factory::setUseForwardHeaders); - } - - private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, ServerOptions serverOptions) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this.undertowProperties::getBufferSize) - .whenNonNull() - .asInt(DataSize::toBytes) - .to(factory::setBufferSize); - UndertowServerProperties.Threads threadProperties = this.undertowProperties.getThreads(); - map.from(threadProperties::getIo).to(factory::setIoThreads); - map.from(threadProperties::getWorker).to(factory::setWorkerThreads); - map.from(this.undertowProperties::getDirectBuffers).to(factory::setUseDirectBuffers); - map.from(this.undertowProperties::getMaxHttpPostSize) - .as(DataSize::toBytes) - .when(this::isPositive) - .to(serverOptions.option(UndertowOptions.MAX_ENTITY_SIZE)); - map.from(this.undertowProperties::getMaxParameters).to(serverOptions.option(UndertowOptions.MAX_PARAMETERS)); - map.from(this.undertowProperties::getMaxHeaders).to(serverOptions.option(UndertowOptions.MAX_HEADERS)); - map.from(this.undertowProperties::getMaxCookies).to(serverOptions.option(UndertowOptions.MAX_COOKIES)); - mapSlashProperty(this.undertowProperties, serverOptions); - map.from(this.undertowProperties::isDecodeUrl).to(serverOptions.option(UndertowOptions.DECODE_URL)); - map.from(this.undertowProperties::getUrlCharset) - .as(Charset::name) - .to(serverOptions.option(UndertowOptions.URL_CHARSET)); - map.from(this.undertowProperties::isAlwaysSetKeepAlive) - .to(serverOptions.option(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)); - map.from(this.undertowProperties::getNoRequestTimeout) - .asInt(Duration::toMillis) - .to(serverOptions.option(UndertowOptions.NO_REQUEST_TIMEOUT)); - map.from(this.undertowProperties.getOptions()::getServer).to(serverOptions.forEach(serverOptions::option)); - SocketOptions socketOptions = new SocketOptions(factory); - map.from(this.undertowProperties.getOptions()::getSocket).to(socketOptions.forEach(socketOptions::option)); - } - - private void mapSlashProperty(UndertowServerProperties properties, ServerOptions serverOptions) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(properties::getDecodeSlash).to(serverOptions.option(UndertowOptions.DECODE_SLASH)); - - } - - private boolean isPositive(Number value) { - return value.longValue() > 0; - } - - private void mapAccessLogProperties(ConfigurableUndertowWebServerFactory factory) { - Accesslog properties = this.undertowProperties.getAccesslog(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(properties::isEnabled).to(factory::setAccessLogEnabled); - map.from(properties::getDir).to(factory::setAccessLogDirectory); - map.from(properties::getPattern).to(factory::setAccessLogPattern); - map.from(properties::getPrefix).to(factory::setAccessLogPrefix); - map.from(properties::getSuffix).to(factory::setAccessLogSuffix); - map.from(properties::isRotate).to(factory::setAccessLogRotate); - } - - private boolean getOrDeduceUseForwardHeaders() { - if (this.serverProperties.getForwardHeadersStrategy() == null) { - CloudPlatform platform = CloudPlatform.getActive(this.environment); - return platform != null && platform.isUsingForwardHeaders(); - } - return this.serverProperties.getForwardHeadersStrategy().equals(ServerProperties.ForwardHeadersStrategy.NATIVE); - } - - private abstract static class AbstractOptions { - - private final Class source; - - private final Map> nameLookup; - - private final ConfigurableUndertowWebServerFactory factory; - - AbstractOptions(Class source, ConfigurableUndertowWebServerFactory factory) { - Map> lookup = new HashMap<>(); - ReflectionUtils.doWithLocalFields(source, (field) -> { - int modifiers = field.getModifiers(); - if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) - && Option.class.isAssignableFrom(field.getType())) { - try { - Option option = (Option) field.get(null); - lookup.put(getCanonicalName(field.getName()), option); - } - catch (IllegalAccessException ex) { - // Ignore - } - } - }); - this.source = source; - this.nameLookup = Collections.unmodifiableMap(lookup); - this.factory = factory; - } - - protected ConfigurableUndertowWebServerFactory getFactory() { - return this.factory; - } - - @SuppressWarnings("unchecked") - Consumer> forEach(Function, Consumer> function) { - return (map) -> map.forEach((key, value) -> { - Option option = (Option) this.nameLookup.get(getCanonicalName(key)); - Assert.state(option != null, - () -> "Unable to find '" + key + "' in " + ClassUtils.getShortName(this.source)); - T parsed = option.parseValue(value, getClass().getClassLoader()); - function.apply(option).accept(parsed); - }); - } - - private static String getCanonicalName(String name) { - StringBuilder canonicalName = new StringBuilder(name.length()); - name.chars() - .filter(Character::isLetterOrDigit) - .map(Character::toLowerCase) - .forEach((c) -> canonicalName.append((char) c)); - return canonicalName.toString(); - } - - } - - /** - * {@link ConfigurableUndertowWebServerFactory} wrapper that makes it easier to apply - * {@link UndertowOptions server options}. - */ - private static class ServerOptions extends AbstractOptions { - - ServerOptions(ConfigurableUndertowWebServerFactory factory) { - super(UndertowOptions.class, factory); - } - - Consumer option(Option option) { - return (value) -> getFactory().addBuilderCustomizers((builder) -> builder.setServerOption(option, value)); - } - - } - - /** - * {@link ConfigurableUndertowWebServerFactory} wrapper that makes it easier to apply - * {@link Options socket options}. - */ - private static class SocketOptions extends AbstractOptions { - - SocketOptions(ConfigurableUndertowWebServerFactory factory) { - super(Options.class, factory); - } - - Consumer option(Option option) { - return (value) -> getFactory().addBuilderCustomizers((builder) -> builder.setSocketOption(option, value)); - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowAccessLogCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowAccessLogCustomizer.java deleted file mode 100644 index f709977dc78..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowAccessLogCustomizer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import java.util.function.Function; - -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer; -import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; - -/** - * {@link AccessLogCustomizer} for Undertow. - * - * @param the type of factory that can be customized - * @author Andy Wilkinson - */ -class UndertowAccessLogCustomizer extends AccessLogCustomizer { - - private final Function accessLogPrefixExtractor; - - UndertowAccessLogCustomizer(UndertowManagementServerProperties properties, - Function accessLogPrefixExtractor) { - super(properties.getAccesslog().getPrefix()); - this.accessLogPrefixExtractor = accessLogPrefixExtractor; - } - - @Override - public void customize(T factory) { - factory.setAccessLogPrefix(customizePrefix(this.accessLogPrefixExtractor.apply(factory))); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowManagementServerProperties.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowManagementServerProperties.java deleted file mode 100644 index 9400572e670..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowManagementServerProperties.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Properties for an Undertow-based management server. - * - * @author Moritz Halbritter - * @since 4.0.0 - */ -@ConfigurationProperties("management.server.undertow") -public class UndertowManagementServerProperties { - - private final Accesslog accesslog = new Accesslog(); - - public Accesslog getAccesslog() { - return this.accesslog; - } - - public static class Accesslog { - - /** - * Management log file name prefix. - */ - private String prefix = "management_"; - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementChildContextConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementChildContextConfiguration.java deleted file mode 100644 index 09427064f45..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementChildContextConfiguration.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import io.undertow.Undertow; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration; -import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; -import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; - -/** - * {@link ManagementContextConfiguration @ManagementContextConfiguration} for - * Undertow-based reactive web endpoint infrastructure when a separate management context - * running on a different port is required. - * - * @author Andy Wilkinson - */ -@ConditionalOnClass(Undertow.class) -@ConditionalOnWebApplication(type = Type.REACTIVE) -@EnableConfigurationProperties(UndertowManagementServerProperties.class) -@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) -class UndertowReactiveManagementChildContextConfiguration { - - @Bean - static ManagementContextFactory reactiveWebChildContextFactory() { - return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, - UndertowReactiveWebServerAutoConfiguration.class); - } - - @Bean - UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer( - UndertowManagementServerProperties properties) { - return new UndertowAccessLogCustomizer<>(properties, UndertowReactiveWebServerFactory::getAccessLogPrefix); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementContextAutoConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementContextAutoConfiguration.java deleted file mode 100644 index ccf37073ab5..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowReactiveManagementContextAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import io.undertow.Undertow; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextFactory; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration; -import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; - -/** - * Auto-configuration for an Undertow-based reactive management context. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -@AutoConfiguration -@ConditionalOnClass({ Undertow.class, ManagementContextFactory.class }) -@ConditionalOnWebApplication(type = Type.REACTIVE) -@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) -public final class UndertowReactiveManagementContextAutoConfiguration { - - @Bean - static ManagementContextFactory reactiveWebChildContextFactory() { - return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, - UndertowReactiveWebServerAutoConfiguration.class); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementChildContextConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementChildContextConfiguration.java deleted file mode 100644 index 6bc529e4d36..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementChildContextConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import io.undertow.Undertow; - -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.context.annotation.Bean; - -/** - * {@link ManagementContextConfiguration @ManagementContextConfiguration} for - * Undertow-based servlet web endpoint infrastructure when a separate management context - * running on a different port is required. - * - * @author Andy Wilkinson - */ -@ConditionalOnClass(Undertow.class) -@ConditionalOnWebApplication(type = Type.SERVLET) -@EnableConfigurationProperties(UndertowManagementServerProperties.class) -@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) -class UndertowServletManagementChildContextConfiguration { - - @Bean - UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer( - UndertowManagementServerProperties properties) { - return new UndertowAccessLogCustomizer<>(properties, UndertowServletWebServerFactory::getAccessLogPrefix); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementContextAutoConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementContextAutoConfiguration.java deleted file mode 100644 index 832842ca036..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/UndertowServletManagementContextAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import io.undertow.Undertow; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextFactory; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.undertow.autoconfigure.servlet.UndertowServletWebServerAutoConfiguration; -import org.springframework.boot.web.server.servlet.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; - -/** - * Auto-configuration for an Undertow-based servlet management context. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -@AutoConfiguration -@ConditionalOnClass({ Undertow.class, ManagementContextFactory.class }) -@ConditionalOnWebApplication(type = Type.SERVLET) -@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) -public final class UndertowServletManagementContextAutoConfiguration { - - @Bean - static ManagementContextFactory servletWebChildContextFactory() { - return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class, - UndertowServletWebServerAutoConfiguration.class); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/package-info.java deleted file mode 100644 index 63f89d3bc9e..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/server/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator Undertow actuator web concerns. - */ -@NullMarked -package org.springframework.boot.undertow.autoconfigure.actuate.web.server; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java deleted file mode 100644 index 987f5fff791..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Classes related to the auto-configuration of a servlet or reactive web server using - * Undertow. - */ -@NullMarked -package org.springframework.boot.undertow.autoconfigure; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java deleted file mode 100644 index f399ac26919..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.reactive; - -import io.undertow.Undertow; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; -import org.springframework.boot.undertow.autoconfigure.UndertowWebServerConfiguration; -import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; -import org.springframework.boot.web.server.autoconfigure.reactive.ReactiveWebServerConfiguration; -import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.ReactiveHttpInputMessage; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based reactive web - * server. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -@AutoConfiguration -@ConditionalOnClass({ ReactiveHttpInputMessage.class, Undertow.class }) -@ConditionalOnWebApplication(type = Type.REACTIVE) -@EnableConfigurationProperties(UndertowServerProperties.class) -@Import({ UndertowWebServerConfiguration.class, ReactiveWebServerConfiguration.class }) -public final class UndertowReactiveWebServerAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(ReactiveWebServerFactory.class) - UndertowReactiveWebServerFactory undertowReactiveWebServerFactory( - ObjectProvider builderCustomizers) { - UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory(); - factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); - return factory; - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java deleted file mode 100644 index 14d12b37961..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Classes related to the auto-configuration of a reactive web server using Undertow. - */ -@NullMarked -package org.springframework.boot.undertow.autoconfigure.reactive; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java deleted file mode 100644 index 4e66cf4b477..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import io.undertow.Undertow; -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.websockets.jsr.Bootstrap; -import jakarta.servlet.ServletRequest; -import org.xnio.SslClientAuthMode; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.thread.Threading; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; -import org.springframework.boot.undertow.autoconfigure.UndertowWebServerConfiguration; -import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.autoconfigure.servlet.ServletWebServerConfiguration; -import org.springframework.boot.web.server.servlet.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.task.VirtualThreadTaskExecutor; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based servlet web - * server. - * - * @author Andy Wilkinson - * @since 4.0.0 - */ -@AutoConfiguration -@ConditionalOnClass({ ServletRequest.class, Undertow.class, SslClientAuthMode.class, DeploymentInfo.class }) -@ConditionalOnWebApplication(type = Type.SERVLET) -@EnableConfigurationProperties(UndertowServerProperties.class) -@Import({ UndertowWebServerConfiguration.class, ServletWebServerConfiguration.class }) -public final class UndertowServletWebServerAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) - UndertowServletWebServerFactory undertowServletWebServerFactory( - ObjectProvider deploymentInfoCustomizers, - ObjectProvider builderCustomizers) { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); - factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList()); - factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); - return factory; - } - - @Bean - UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer( - UndertowServerProperties undertowProperties) { - return new UndertowServletWebServerFactoryCustomizer(undertowProperties); - } - - @Bean - @ConditionalOnThreading(Threading.VIRTUAL) - UndertowDeploymentInfoCustomizer virtualThreadsUndertowDeploymentInfoCustomizer() { - return (deploymentInfo) -> deploymentInfo.setExecutor(new VirtualThreadTaskExecutor("undertow-")); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Bootstrap.class) - static class UndertowWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") - WebSocketUndertowServletWebServerFactoryCustomizer websocketServletWebServerCustomizer() { - return new WebSocketUndertowServletWebServerFactoryCustomizer(); - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java deleted file mode 100644 index c354bff5795..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.server.autoconfigure.ServerProperties; - -/** - * {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Undertow - * Servlet web servers. - * - * @author Andy Wilkinson - */ -class UndertowServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer { - - private final UndertowServerProperties undertowProperties; - - UndertowServletWebServerFactoryCustomizer(UndertowServerProperties undertowProperties) { - this.undertowProperties = undertowProperties; - } - - @Override - public void customize(UndertowServletWebServerFactory factory) { - factory.setEagerFilterInit(this.undertowProperties.isEagerFilterInit()); - factory.setPreservePathOnForward(this.undertowProperties.isPreservePathOnForward()); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java deleted file mode 100644 index 3db28703f37..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.websockets.jsr.WebSocketDeploymentInfo; - -import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link UndertowServletWebServerFactory}. - * - * @author Phillip Webb - * @since 4.0.0 - */ -public class WebSocketUndertowServletWebServerFactoryCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(UndertowServletWebServerFactory factory) { - WebsocketDeploymentInfoCustomizer customizer = new WebsocketDeploymentInfoCustomizer(); - factory.addDeploymentInfoCustomizers(customizer); - } - - @Override - public int getOrder() { - return 0; - } - - private static final class WebsocketDeploymentInfoCustomizer implements UndertowDeploymentInfoCustomizer { - - @Override - public void customize(DeploymentInfo deploymentInfo) { - WebSocketDeploymentInfo info = new WebSocketDeploymentInfo(); - deploymentInfo.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, info); - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java deleted file mode 100644 index e7c5fd2982f..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Classes related to the auto-configuration of a servlet web server using Undertow. - */ -@NullMarked -package org.springframework.boot.undertow.autoconfigure.servlet; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java deleted file mode 100644 index 42a96fed990..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Reactive and servlet web server implementations backed by Undertow. - * - * @see org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory - * @see org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory - */ -@NullMarked -package org.springframework.boot.undertow; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java deleted file mode 100644 index 1186df74cf3..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.reactive; - -import java.util.List; - -import io.undertow.Undertow; - -import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; -import org.springframework.boot.undertow.HttpHandlerFactory; -import org.springframework.boot.undertow.UndertowWebServer; -import org.springframework.boot.undertow.UndertowWebServerFactory; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; -import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; -import org.springframework.http.server.reactive.UndertowHttpHandlerAdapter; - -/** - * {@link ReactiveWebServerFactory} that can be used to create {@link UndertowWebServer}s. - * - * @author Brian Clozel - * @author Scott Frederick - * @since 4.0.0 - */ -public class UndertowReactiveWebServerFactory extends UndertowWebServerFactory - implements ConfigurableUndertowWebServerFactory, ConfigurableReactiveWebServerFactory { - - /** - * Create a new {@link UndertowReactiveWebServerFactory} instance. - */ - public UndertowReactiveWebServerFactory() { - } - - /** - * Create a new {@link UndertowReactiveWebServerFactory} that listens for requests - * using the specified port. - * @param port the port to listen on - */ - public UndertowReactiveWebServerFactory(int port) { - super(port); - } - - @Override - public WebServer getWebServer(org.springframework.http.server.reactive.HttpHandler httpHandler) { - Undertow.Builder builder = createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); - List httpHandlerFactories = createHttpHandlerFactories(this, - (next) -> new UndertowHttpHandlerAdapter(httpHandler)); - return new UndertowWebServer(builder, httpHandlerFactories, getPort() >= 0); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java deleted file mode 100644 index cdf63cc51a1..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Reactive web server implementation backed by Undertow. - */ -@NullMarked -package org.springframework.boot.undertow.reactive; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java deleted file mode 100644 index b774bd9abdb..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import io.undertow.UndertowMessages; -import io.undertow.server.handlers.resource.Resource; -import io.undertow.server.handlers.resource.ResourceChangeListener; -import io.undertow.server.handlers.resource.ResourceManager; -import org.jspecify.annotations.Nullable; - -/** - * A {@link ResourceManager} that delegates to multiple {@code ResourceManager} instances. - * - * @author Andy Wilkinson - */ -class CompositeResourceManager implements ResourceManager { - - private final List resourceManagers; - - CompositeResourceManager(ResourceManager... resourceManagers) { - this.resourceManagers = Arrays.asList(resourceManagers); - } - - @Override - public void close() throws IOException { - for (ResourceManager resourceManager : this.resourceManagers) { - resourceManager.close(); - } - } - - @Override - public @Nullable Resource getResource(String path) throws IOException { - for (ResourceManager resourceManager : this.resourceManagers) { - Resource resource = resourceManager.getResource(path); - if (resource != null) { - return resource; - } - } - return null; - } - - @Override - public boolean isResourceChangeListenerSupported() { - return false; - } - - @Override - public void registerResourceChangeListener(ResourceChangeListener listener) { - throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); - } - - @Override - public void removeResourceChangeListener(ResourceChangeListener listener) { - throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java deleted file mode 100644 index 16116a63e8d..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.Closeable; -import java.io.IOException; - -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; -import io.undertow.servlet.api.DeploymentManager; -import jakarta.servlet.ServletException; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.undertow.HttpHandlerFactory; -import org.springframework.util.Assert; - -/** - * {@link HttpHandlerFactory} that for a {@link DeploymentManager}. - * - * @author Andy Wilkinson - * @author Phillip Webb - */ -class DeploymentManagerHttpHandlerFactory implements HttpHandlerFactory { - - private final DeploymentManager deploymentManager; - - DeploymentManagerHttpHandlerFactory(DeploymentManager deploymentManager) { - this.deploymentManager = deploymentManager; - } - - @Override - public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) { - Assert.state(next == null, "DeploymentManagerHttpHandlerFactory must be first"); - return new DeploymentManagerHandler(this.deploymentManager); - } - - DeploymentManager getDeploymentManager() { - return this.deploymentManager; - } - - /** - * {@link HttpHandler} that delegates to a {@link DeploymentManager}. - */ - static class DeploymentManagerHandler implements HttpHandler, Closeable { - - private final DeploymentManager deploymentManager; - - private final HttpHandler handler; - - DeploymentManagerHandler(DeploymentManager deploymentManager) { - this.deploymentManager = deploymentManager; - try { - this.handler = deploymentManager.start(); - } - catch (ServletException ex) { - throw new RuntimeException(ex); - } - } - - @Override - public void handleRequest(HttpServerExchange exchange) throws Exception { - this.handler.handleRequest(exchange); - } - - @Override - public void close() throws IOException { - try { - this.deploymentManager.stop(); - this.deploymentManager.undeploy(); - } - catch (ServletException ex) { - throw new RuntimeException(ex); - } - } - - DeploymentManager getDeploymentManager() { - return this.deploymentManager; - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java deleted file mode 100644 index d3e4c7f74b9..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; - -import io.undertow.servlet.UndertowServletLogger; -import io.undertow.servlet.api.SessionPersistenceManager; -import org.jspecify.annotations.Nullable; - -import org.springframework.core.ConfigurableObjectInputStream; - -/** - * {@link SessionPersistenceManager} that stores session information in a file. - * - * @author Phillip Webb - * @author Peter Leibiger - * @author Raja Kolli - */ -class FileSessionPersistence implements SessionPersistenceManager { - - private final File dir; - - FileSessionPersistence(File dir) { - this.dir = dir; - } - - @Override - public void persistSessions(String deploymentName, Map sessionData) { - try { - save(sessionData, getSessionFile(deploymentName)); - } - catch (Exception ex) { - UndertowServletLogger.ROOT_LOGGER.failedToPersistSessions(ex); - } - } - - private void save(Map sessionData, File file) throws IOException { - try (ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(file))) { - save(sessionData, stream); - } - } - - private void save(Map sessionData, ObjectOutputStream stream) throws IOException { - Map session = new LinkedHashMap<>(); - sessionData.forEach((key, value) -> session.put(key, new SerializablePersistentSession(value))); - stream.writeObject(session); - } - - @Override - public @Nullable Map loadSessionAttributes(String deploymentName, - final ClassLoader classLoader) { - try { - File file = getSessionFile(deploymentName); - if (file.exists()) { - return load(file, classLoader); - } - } - catch (Exception ex) { - UndertowServletLogger.ROOT_LOGGER.failedtoLoadPersistentSessions(ex); - } - return null; - } - - private Map load(File file, ClassLoader classLoader) - throws IOException, ClassNotFoundException { - try (ObjectInputStream stream = new ConfigurableObjectInputStream(new FileInputStream(file), classLoader)) { - return load(stream); - } - } - - private Map load(ObjectInputStream stream) throws ClassNotFoundException, IOException { - Map session = readSession(stream); - long time = System.currentTimeMillis(); - Map result = new LinkedHashMap<>(); - session.forEach((key, value) -> { - PersistentSession entrySession = value.getPersistentSession(); - if (entrySession.getExpiration().getTime() > time) { - result.put(key, entrySession); - } - }); - return result; - } - - @SuppressWarnings("unchecked") - private Map readSession(ObjectInputStream stream) - throws ClassNotFoundException, IOException { - return ((Map) stream.readObject()); - } - - private File getSessionFile(String deploymentName) { - if (!this.dir.exists()) { - this.dir.mkdirs(); - } - return new File(this.dir, deploymentName + ".session"); - } - - @Override - public void clear(String deploymentName) { - getSessionFile(deploymentName).delete(); - } - - /** - * Session data in a serializable form. - */ - static class SerializablePersistentSession implements Serializable { - - private static final long serialVersionUID = 0L; - - private final Date expiration; - - private final Map sessionData; - - SerializablePersistentSession(PersistentSession session) { - this.expiration = session.getExpiration(); - this.sessionData = new LinkedHashMap<>(session.getSessionData()); - } - - PersistentSession getPersistentSession() { - return new PersistentSession(this.expiration, this.sessionData); - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java deleted file mode 100644 index e1e5cfa64a9..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; - -import io.undertow.UndertowMessages; -import io.undertow.server.handlers.resource.Resource; -import io.undertow.server.handlers.resource.ResourceChangeListener; -import io.undertow.server.handlers.resource.ResourceManager; -import io.undertow.server.handlers.resource.URLResource; -import org.jspecify.annotations.Nullable; - -import org.springframework.util.StringUtils; - -/** - * {@link ResourceManager} for JAR resources. - * - * @author Ivan Sopov - * @author Andy Wilkinson - */ -class JarResourceManager implements ResourceManager { - - private final String jarPath; - - JarResourceManager(File jarFile) { - try { - this.jarPath = jarFile.getAbsoluteFile().toURI().toURL().toString(); - } - catch (MalformedURLException ex) { - throw new IllegalArgumentException(ex); - } - } - - @Override - public @Nullable Resource getResource(String path) throws IOException { - URL url = new URL("jar:" + this.jarPath + "!" + (path.startsWith("/") ? path : "/" + path)); - URLResource resource = new URLResource(url, path); - if (StringUtils.hasText(path) && !"/".equals(path) && resource.getContentLength() < 0) { - return null; - } - return resource; - } - - @Override - public boolean isResourceChangeListenerSupported() { - return false; - } - - @Override - public void registerResourceChangeListener(ResourceChangeListener listener) { - throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); - - } - - @Override - public void removeResourceChangeListener(ResourceChangeListener listener) { - throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); - } - - @Override - public void close() throws IOException { - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java deleted file mode 100644 index 194f6d0a843..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import io.undertow.servlet.api.DeploymentInfo; - -/** - * Callback interface that can be used to customize an Undertow {@link DeploymentInfo}. - * - * @author Phillip Webb - * @since 4.0.0 - * @see UndertowServletWebServerFactory - */ -@FunctionalInterface -public interface UndertowDeploymentInfoCustomizer { - - /** - * Customize the deployment info. - * @param deploymentInfo the {@code DeploymentInfo} to customize - */ - void customize(DeploymentInfo deploymentInfo); - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java deleted file mode 100644 index 2ee17fb7e2b..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import io.undertow.Handlers; -import io.undertow.Undertow.Builder; -import io.undertow.server.HttpHandler; -import io.undertow.servlet.api.DeploymentManager; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.undertow.HttpHandlerFactory; -import org.springframework.boot.undertow.UndertowWebServer; -import org.springframework.boot.web.server.WebServer; -import org.springframework.util.StringUtils; - -/** - * {@link WebServer} that can be used to control an embedded Undertow server. Typically - * this class should be created using {@link UndertowServletWebServerFactory} and not - * directly. - * - * @author Ivan Sopov - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Christoph Dreis - * @author Kristine Jetzke - * @since 4.0.0 - * @see UndertowServletWebServerFactory - */ -public class UndertowServletWebServer extends UndertowWebServer { - - private final String contextPath; - - private final @Nullable DeploymentManager manager; - - /** - * Create a new {@link UndertowServletWebServer} instance. - * @param builder the builder - * @param httpHandlerFactories the handler factories - * @param contextPath the root context path - * @param autoStart if the server should be started - * @since 4.0.0 - */ - public UndertowServletWebServer(Builder builder, Iterable httpHandlerFactories, - String contextPath, boolean autoStart) { - super(builder, httpHandlerFactories, autoStart); - this.contextPath = contextPath; - this.manager = findManager(httpHandlerFactories); - } - - private @Nullable DeploymentManager findManager(Iterable httpHandlerFactories) { - for (HttpHandlerFactory httpHandlerFactory : httpHandlerFactories) { - if (httpHandlerFactory instanceof DeploymentManagerHttpHandlerFactory deploymentManagerFactory) { - return deploymentManagerFactory.getDeploymentManager(); - } - } - return null; - } - - @Override - protected @Nullable HttpHandler createHttpHandler() { - HttpHandler handler = super.createHttpHandler(); - if (StringUtils.hasLength(this.contextPath)) { - handler = Handlers.path().addPrefixPath(this.contextPath, handler); - } - return handler; - } - - @Override - protected String getStartedLogMessage() { - String contextPath = StringUtils.hasText(this.contextPath) ? this.contextPath : "/"; - StringBuilder message = new StringBuilder(super.getStartedLogMessage()); - message.append(" with context path '"); - message.append(contextPath); - message.append("'"); - return message.toString(); - } - - public @Nullable DeploymentManager getDeploymentManager() { - return this.manager; - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java deleted file mode 100644 index a69f309daec..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EventListener; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; - -import io.undertow.Undertow.Builder; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; -import io.undertow.server.handlers.Cookie; -import io.undertow.server.handlers.resource.FileResourceManager; -import io.undertow.server.handlers.resource.Resource; -import io.undertow.server.handlers.resource.ResourceChangeListener; -import io.undertow.server.handlers.resource.ResourceManager; -import io.undertow.server.handlers.resource.URLResource; -import io.undertow.server.session.SessionManager; -import io.undertow.servlet.Servlets; -import io.undertow.servlet.api.Deployment; -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.servlet.api.DeploymentManager; -import io.undertow.servlet.api.ListenerInfo; -import io.undertow.servlet.api.MimeMapping; -import io.undertow.servlet.api.ServletContainerInitializerInfo; -import io.undertow.servlet.api.ServletStackTraces; -import io.undertow.servlet.core.DeploymentImpl; -import io.undertow.servlet.handlers.DefaultServlet; -import io.undertow.servlet.util.ImmediateInstanceFactory; -import jakarta.servlet.ServletContainerInitializer; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jspecify.annotations.Nullable; - -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.undertow.HttpHandlerFactory; -import org.springframework.boot.undertow.UndertowWebServerFactory; -import org.springframework.boot.web.error.ErrorPage; -import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.MimeMappings.Mapping; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.server.servlet.ContextPath; -import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; -import org.springframework.boot.web.server.servlet.DocumentRoot; -import org.springframework.boot.web.server.servlet.ServletContextInitializers; -import org.springframework.boot.web.server.servlet.ServletWebServerFactory; -import org.springframework.boot.web.server.servlet.ServletWebServerSettings; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -/** - * {@link ServletWebServerFactory} that can be used to create - * {@link UndertowServletWebServer}s. - *

- * Unless explicitly configured otherwise, the factory will create servers that listen for - * HTTP requests on port 8080. - * - * @author Ivan Sopov - * @author Andy Wilkinson - * @author Marcos Barbero - * @author Eddú Meléndez - * @author Scott Frederick - * @since 4.0.0 - * @see UndertowServletWebServer - */ -public class UndertowServletWebServerFactory extends UndertowWebServerFactory - implements ConfigurableServletWebServerFactory, ResourceLoaderAware { - - private static final Log logger = LogFactory.getLog(UndertowServletWebServerFactory.class); - - private static final Pattern ENCODED_SLASH = Pattern.compile("%2F", Pattern.LITERAL); - - private static final Set> NO_CLASSES = Collections.emptySet(); - - private final ServletWebServerSettings settings = new ServletWebServerSettings(); - - private Set deploymentInfoCustomizers = new LinkedHashSet<>(); - - @SuppressWarnings("NullAway.Init") - private ResourceLoader resourceLoader; - - private boolean eagerFilterInit = true; - - private boolean preservePathOnForward; - - /** - * Create a new {@link UndertowServletWebServerFactory} instance. - */ - public UndertowServletWebServerFactory() { - getSettings().getJsp().setRegistered(false); - } - - /** - * Create a new {@link UndertowServletWebServerFactory} that listens for requests - * using the specified port. - * @param port the port to listen on - */ - public UndertowServletWebServerFactory(int port) { - super(port); - getSettings().getJsp().setRegistered(false); - } - - /** - * Create a new {@link UndertowServletWebServerFactory} with the specified context - * path and port. - * @param contextPath the root context path - * @param port the port to listen on - */ - public UndertowServletWebServerFactory(String contextPath, int port) { - super(port); - getSettings().setContextPath(ContextPath.of(contextPath)); - getSettings().getJsp().setRegistered(false); - } - - /** - * Returns a mutable collection of the {@link UndertowDeploymentInfoCustomizer}s that - * will be applied to the Undertow {@link DeploymentInfo}. - * @return the customizers that will be applied - */ - public Collection getDeploymentInfoCustomizers() { - return this.deploymentInfoCustomizers; - } - - /** - * Set {@link UndertowDeploymentInfoCustomizer}s that should be applied to the - * Undertow {@link DeploymentInfo}. Calling this method will replace any existing - * customizers. - * @param customizers the customizers to set - */ - public void setDeploymentInfoCustomizers(Collection customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.deploymentInfoCustomizers = new LinkedHashSet<>(customizers); - } - - /** - * Add {@link UndertowDeploymentInfoCustomizer}s that should be used to customize the - * Undertow {@link DeploymentInfo}. - * @param customizers the customizers to add - */ - public void addDeploymentInfoCustomizers(UndertowDeploymentInfoCustomizer... customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.deploymentInfoCustomizers.addAll(Arrays.asList(customizers)); - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - /** - * Return if filters should be eagerly initialized. - * @return {@code true} if filters are eagerly initialized, otherwise {@code false}. - */ - public boolean isEagerFilterInit() { - return this.eagerFilterInit; - } - - /** - * Set whether filters should be eagerly initialized. - * @param eagerFilterInit {@code true} if filters are eagerly initialized, otherwise - * {@code false}. - */ - public void setEagerFilterInit(boolean eagerFilterInit) { - this.eagerFilterInit = eagerFilterInit; - } - - /** - * Return whether the request path should be preserved on forward. - * @return {@code true} if the path should be preserved when a request is forwarded, - * otherwise {@code false}. - */ - public boolean isPreservePathOnForward() { - return this.preservePathOnForward; - } - - /** - * Set whether the request path should be preserved on forward. - * @param preservePathOnForward {@code true} if the path should be preserved when a - * request is forwarded, otherwise {@code false}. - */ - public void setPreservePathOnForward(boolean preservePathOnForward) { - this.preservePathOnForward = preservePathOnForward; - } - - @Override - public WebServer getWebServer(ServletContextInitializer... initializers) { - Builder builder = createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); - DeploymentManager manager = createManager(initializers); - return getUndertowWebServer(builder, manager, getPort()); - } - - private DeploymentManager createManager(ServletContextInitializer... initializers) { - DeploymentInfo deployment = Servlets.deployment(); - registerServletContainerInitializerToDriveServletContextInitializers(deployment, initializers); - deployment.setClassLoader(getServletClassLoader()); - deployment.setContextPath(getSettings().getContextPath().toString()); - deployment.setDisplayName(getSettings().getDisplayName()); - deployment.setDeploymentName("spring-boot"); - if (getSettings().isRegisterDefaultServlet()) { - deployment.addServlet(Servlets.servlet("default", DefaultServlet.class)); - } - configureErrorPages(deployment); - deployment.setServletStackTraces(ServletStackTraces.NONE); - deployment.setResourceManager(getDocumentRootResourceManager()); - deployment.setTempDir(createTempDir("undertow")); - deployment.setEagerFilterInit(this.eagerFilterInit); - deployment.setPreservePathOnForward(this.preservePathOnForward); - configureMimeMappings(deployment); - configureWebListeners(deployment); - for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) { - customizer.customize(deployment); - } - if (getSettings().getSession().isPersistent()) { - File dir = getSettings().getSession().getSessionStoreDirectory().getValidDirectory(true); - deployment.setSessionPersistenceManager(new FileSessionPersistence(dir)); - } - addLocaleMappings(deployment); - DeploymentManager manager = Servlets.newContainer().addDeployment(deployment); - manager.deploy(); - if (manager.getDeployment() instanceof DeploymentImpl managerDeployment) { - removeSuperfluousMimeMappings(managerDeployment, deployment); - } - SessionManager sessionManager = manager.getDeployment().getSessionManager(); - Duration timeoutDuration = getSettings().getSession().getTimeout(); - int sessionTimeout = (isZeroOrLess(timeoutDuration) ? -1 : (int) timeoutDuration.getSeconds()); - sessionManager.setDefaultSessionTimeout(sessionTimeout); - return manager; - } - - private void configureWebListeners(DeploymentInfo deployment) { - for (String className : getSettings().getWebListenerClassNames()) { - try { - deployment.addListener(new ListenerInfo(loadWebListenerClass(className))); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException("Failed to load web listener class '" + className + "'", ex); - } - } - } - - @SuppressWarnings("unchecked") - private Class loadWebListenerClass(String className) throws ClassNotFoundException { - ClassLoader classLoader = getServletClassLoader(); - Assert.state(classLoader != null, "'classLoader' must not be null"); - return (Class) classLoader.loadClass(className); - } - - private boolean isZeroOrLess(@Nullable Duration timeoutDuration) { - return timeoutDuration == null || timeoutDuration.isZero() || timeoutDuration.isNegative(); - } - - private void addLocaleMappings(DeploymentInfo deployment) { - getSettings().getLocaleCharsetMappings() - .forEach((locale, charset) -> deployment.addLocaleCharsetMapping(locale.toString(), charset.toString())); - } - - private void registerServletContainerInitializerToDriveServletContextInitializers(DeploymentInfo deployment, - ServletContextInitializer... initializers) { - ServletContextInitializers mergedInitializers = ServletContextInitializers.from(this.settings, initializers); - Initializer initializer = new Initializer(mergedInitializers); - deployment.addServletContainerInitializer(new ServletContainerInitializerInfo(Initializer.class, - new ImmediateInstanceFactory<>(initializer), NO_CLASSES)); - } - - private @Nullable ClassLoader getServletClassLoader() { - if (this.resourceLoader != null) { - return this.resourceLoader.getClassLoader(); - } - return getClass().getClassLoader(); - } - - private ResourceManager getDocumentRootResourceManager() { - DocumentRoot documentRoot = new DocumentRoot(logger); - documentRoot.setDirectory(this.settings.getDocumentRoot()); - File root = documentRoot.getValidDirectory(); - File docBase = getCanonicalDocumentRoot(root); - List metaInfResourceUrls = getSettings().getStaticResourceUrls(); - List resourceJarUrls = new ArrayList<>(); - List managers = new ArrayList<>(); - ResourceManager rootManager = (docBase.isDirectory() ? new FileResourceManager(docBase, 0) - : new JarResourceManager(docBase)); - if (root != null) { - rootManager = new LoaderHidingResourceManager(rootManager); - } - managers.add(rootManager); - for (URL url : metaInfResourceUrls) { - if ("file".equals(url.getProtocol())) { - try { - File file = new File(url.toURI()); - if (file.isFile()) { - resourceJarUrls.add(new URL("jar:" + url + "!/")); - } - else { - managers.add(new FileResourceManager(new File(file, "META-INF/resources"), 0)); - } - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - else { - resourceJarUrls.add(url); - } - } - managers.add(new MetaInfResourcesResourceManager(resourceJarUrls)); - return new CompositeResourceManager(managers.toArray(new ResourceManager[0])); - } - - private File getCanonicalDocumentRoot(@Nullable File docBase) { - try { - File root = (docBase != null) ? docBase : createTempDir("undertow-docbase"); - return root.getCanonicalFile(); - } - catch (IOException ex) { - throw new IllegalStateException("Cannot get canonical document root", ex); - } - } - - private void configureErrorPages(DeploymentInfo deployment) { - for (ErrorPage errorPage : getErrorPages()) { - deployment.addErrorPage(getUndertowErrorPage(errorPage)); - } - } - - private io.undertow.servlet.api.ErrorPage getUndertowErrorPage(ErrorPage errorPage) { - if (errorPage.getStatus() != null) { - return new io.undertow.servlet.api.ErrorPage(errorPage.getPath(), errorPage.getStatusCode()); - } - if (errorPage.getException() != null) { - return new io.undertow.servlet.api.ErrorPage(errorPage.getPath(), errorPage.getException()); - } - return new io.undertow.servlet.api.ErrorPage(errorPage.getPath()); - } - - private void configureMimeMappings(DeploymentInfo deployment) { - for (Mapping mimeMapping : getSettings().getMimeMappings()) { - deployment.addMimeMapping(new MimeMapping(mimeMapping.getExtension(), mimeMapping.getMimeType())); - } - } - - private void removeSuperfluousMimeMappings(DeploymentImpl deployment, DeploymentInfo deploymentInfo) { - // DeploymentManagerImpl will always add MimeMappings.DEFAULT_MIME_MAPPINGS - // but we only want ours - Map mappings = new HashMap<>(); - for (MimeMapping mapping : deploymentInfo.getMimeMappings()) { - mappings.put(mapping.getExtension().toLowerCase(Locale.ENGLISH), mapping.getMimeType()); - } - deployment.setMimeExtensionMappings(mappings); - } - - /** - * Factory method called to create the {@link UndertowServletWebServer}. Subclasses - * can override this method to return a different {@link UndertowServletWebServer} or - * apply additional processing to the {@link Builder} and {@link DeploymentManager} - * used to bootstrap Undertow - * @param builder the builder - * @param manager the deployment manager - * @param port the port that Undertow should listen on - * @return a new {@link UndertowServletWebServer} instance - */ - protected UndertowServletWebServer getUndertowWebServer(Builder builder, DeploymentManager manager, int port) { - List initialHandlerFactories = new ArrayList<>(); - initialHandlerFactories.add(new DeploymentManagerHttpHandlerFactory(manager)); - HttpHandlerFactory cooHandlerFactory = getCookieHandlerFactory(manager.getDeployment()); - if (cooHandlerFactory != null) { - initialHandlerFactories.add(cooHandlerFactory); - } - List httpHandlerFactories = createHttpHandlerFactories(this, - initialHandlerFactories.toArray(new HttpHandlerFactory[0])); - return new UndertowServletWebServer(builder, httpHandlerFactories, getSettings().getContextPath().toString(), - port >= 0); - } - - private @Nullable HttpHandlerFactory getCookieHandlerFactory(Deployment deployment) { - SameSite sessionSameSite = getSettings().getSession().getCookie().getSameSite(); - List suppliers = new ArrayList<>(); - if (sessionSameSite != null) { - String sessionCookieName = deployment.getServletContext().getSessionCookieConfig().getName(); - suppliers.add(CookieSameSiteSupplier.of(sessionSameSite).whenHasName(sessionCookieName)); - } - if (!CollectionUtils.isEmpty(getSettings().getCookieSameSiteSuppliers())) { - suppliers.addAll(getSettings().getCookieSameSiteSuppliers()); - } - return (!suppliers.isEmpty()) ? (next) -> new SuppliedSameSiteCookieHandler(next, suppliers) : null; - } - - @Override - public ServletWebServerSettings getSettings() { - return this.settings; - } - - /** - * {@link ServletContainerInitializer} to initialize {@link ServletContextInitializer - * ServletContextInitializers}. - */ - private static class Initializer implements ServletContainerInitializer { - - private final ServletContextInitializers initializers; - - Initializer(ServletContextInitializers initializers) { - this.initializers = initializers; - } - - @Override - public void onStartup(Set> classes, ServletContext servletContext) throws ServletException { - for (ServletContextInitializer initializer : this.initializers) { - initializer.onStartup(servletContext); - } - } - - } - - /** - * {@link ResourceManager} that exposes resource in {@code META-INF/resources} - * directory of nested (in {@code BOOT-INF/lib} or {@code WEB-INF/lib}) jars. - */ - private static final class MetaInfResourcesResourceManager implements ResourceManager { - - private final List metaInfResourceJarUrls; - - private MetaInfResourcesResourceManager(List metaInfResourceJarUrls) { - this.metaInfResourceJarUrls = metaInfResourceJarUrls; - } - - @Override - public void close() throws IOException { - } - - @Override - public @Nullable Resource getResource(String path) { - for (URL url : this.metaInfResourceJarUrls) { - URLResource resource = getMetaInfResource(url, path); - if (resource != null) { - return resource; - } - } - return null; - } - - @Override - public boolean isResourceChangeListenerSupported() { - return false; - } - - @Override - public void registerResourceChangeListener(ResourceChangeListener listener) { - } - - @Override - public void removeResourceChangeListener(ResourceChangeListener listener) { - - } - - private @Nullable URLResource getMetaInfResource(URL resourceJar, String path) { - try { - String urlPath = URLEncoder.encode(ENCODED_SLASH.matcher(path).replaceAll("/"), StandardCharsets.UTF_8); - URL resourceUrl = new URL(resourceJar + "META-INF/resources" + urlPath); - URLResource resource = new URLResource(resourceUrl, path); - if (resource.getContentLength() < 0) { - return null; - } - return resource; - } - catch (Exception ex) { - return null; - } - } - - } - - /** - * {@link ResourceManager} to hide Spring Boot loader classes. - */ - private static final class LoaderHidingResourceManager implements ResourceManager { - - private final ResourceManager delegate; - - private LoaderHidingResourceManager(ResourceManager delegate) { - this.delegate = delegate; - } - - @Override - public @Nullable Resource getResource(String path) throws IOException { - if (path.startsWith("/org/springframework/boot")) { - return null; - } - return this.delegate.getResource(path); - } - - @Override - public boolean isResourceChangeListenerSupported() { - return this.delegate.isResourceChangeListenerSupported(); - } - - @Override - public void registerResourceChangeListener(ResourceChangeListener listener) { - this.delegate.registerResourceChangeListener(listener); - } - - @Override - public void removeResourceChangeListener(ResourceChangeListener listener) { - this.delegate.removeResourceChangeListener(listener); - } - - @Override - public void close() throws IOException { - this.delegate.close(); - } - - } - - /** - * {@link HttpHandler} to apply {@link CookieSameSiteSupplier supplied} - * {@link SameSite} cookie values. - */ - private static class SuppliedSameSiteCookieHandler implements HttpHandler { - - private final @Nullable HttpHandler next; - - private final List suppliers; - - SuppliedSameSiteCookieHandler(@Nullable HttpHandler next, List suppliers) { - this.next = next; - this.suppliers = suppliers; - } - - @Override - public void handleRequest(HttpServerExchange exchange) throws Exception { - exchange.addResponseCommitListener(this::beforeCommit); - if (this.next != null) { - this.next.handleRequest(exchange); - } - } - - private void beforeCommit(HttpServerExchange exchange) { - for (Cookie cookie : exchange.responseCookies()) { - SameSite sameSite = getSameSite(asServletCookie(cookie)); - if (sameSite == SameSite.OMITTED) { - cookie.setSameSite(false); - } - else if (sameSite != null) { - cookie.setSameSiteMode(sameSite.attributeValue()); - } - } - } - - @SuppressWarnings("removal") - private jakarta.servlet.http.Cookie asServletCookie(Cookie cookie) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - jakarta.servlet.http.Cookie result = new jakarta.servlet.http.Cookie(cookie.getName(), cookie.getValue()); - map.from(cookie::getComment).to(result::setComment); - map.from(cookie::getDomain).to(result::setDomain); - map.from(cookie::getMaxAge).to(result::setMaxAge); - map.from(cookie::getPath).to(result::setPath); - result.setSecure(cookie.isSecure()); - result.setVersion(cookie.getVersion()); - result.setHttpOnly(cookie.isHttpOnly()); - return result; - } - - private @Nullable SameSite getSameSite(jakarta.servlet.http.Cookie cookie) { - for (CookieSameSiteSupplier supplier : this.suppliers) { - SameSite sameSite = supplier.getSameSite(cookie); - if (sameSite != null) { - return sameSite; - } - } - return null; - } - - } - -} diff --git a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java b/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java deleted file mode 100644 index 54f54b26062..00000000000 --- a/module/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Servlet web server implementation backed by Undertow. - */ -@NullMarked -package org.springframework.boot.undertow.servlet; - -import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-undertow/src/main/resources/META-INF/META-INF/spring.factories b/module/spring-boot-undertow/src/main/resources/META-INF/META-INF/spring.factories deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/module/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/module/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 507df419190..00000000000 --- a/module/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "groups": [], - "properties": [ - { - "name": "server.undertow.buffers-per-region", - "type": "java.lang.Integer", - "description": "Number of buffer per region.", - "deprecation": { - "level": "error" - } - } - ] -} diff --git a/module/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories b/module/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories deleted file mode 100644 index ae1653d5ffb..00000000000 --- a/module/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.boot.undertow.UndertowWebServer$UndertowWebServerRuntimeHints diff --git a/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports deleted file mode 100644 index 2329261cdce..00000000000 --- a/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.undertow.autoconfigure.actuate.web.server.UndertowReactiveManagementChildContextConfiguration -org.springframework.boot.undertow.autoconfigure.actuate.web.server.UndertowServletManagementChildContextConfiguration diff --git a/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index a9499430bc6..00000000000 --- a/module/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,4 +0,0 @@ -org.springframework.boot.undertow.autoconfigure.actuate.web.server.UndertowReactiveManagementContextAutoConfiguration -org.springframework.boot.undertow.autoconfigure.actuate.web.server.UndertowServletManagementContextAutoConfiguration -org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration -org.springframework.boot.undertow.autoconfigure.servlet.UndertowServletWebServerAutoConfiguration diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java deleted file mode 100644 index 74a1c155979..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -/** - * Helper class to provide public access to package-private methods for testing purposes. - * - * @author Andy Wilkinson - */ -public final class UndertowAccess { - - private UndertowAccess() { - - } - - public static String getStartedLogMessage(UndertowWebServer undertowWebServer) { - return undertowWebServer.getStartedLogMessage(); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java deleted file mode 100644 index da851e73a93..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow; - -import java.util.function.Predicate; - -import io.undertow.Undertow; -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.undertow.UndertowWebServer.UndertowWebServerRuntimeHints; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowWebServerRuntimeHints}. - * - * @author Andy Wilkinson - */ -class UndertowWebServerRuntimeHintsTests { - - @Test - void registersHints() throws ClassNotFoundException { - RuntimeHints runtimeHints = new RuntimeHints(); - new UndertowWebServerRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onFieldAccess(Undertow.class, "listeners")) - .accepts(runtimeHints); - assertThat(RuntimeHintsPredicates.reflection().onFieldAccess(Undertow.class, "channels")).accepts(runtimeHints); - assertThat(reflectionOnField("io.undertow.Undertow$ListenerConfig", "type")).accepts(runtimeHints); - assertThat(reflectionOnField("io.undertow.Undertow$ListenerConfig", "port")).accepts(runtimeHints); - assertThat(reflectionOnField("io.undertow.protocols.ssl.UndertowAcceptingSslChannel", "ssl")) - .accepts(runtimeHints); - } - - private Predicate reflectionOnField(String className, String fieldName) - throws ClassNotFoundException { - return RuntimeHintsPredicates.reflection() - .onFieldAccess(ReflectionUtils.findField(Class.forName(className), fieldName)); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java deleted file mode 100644 index 6b4b136d6bc..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure; - -import java.util.Collections; -import java.util.Map; - -import io.undertow.UndertowOptions; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowServerProperties}. - * - * @author Andy Wilkinson - */ -class UndertowServerPropertiesTests { - - private final UndertowServerProperties properties = new UndertowServerProperties(); - - @Test - void testCustomizeUndertowServerOption() { - bind("server.undertow.options.server.ALWAYS_SET_KEEP_ALIVE", "true"); - assertThat(this.properties.getOptions().getServer()).containsEntry("ALWAYS_SET_KEEP_ALIVE", "true"); - } - - @Test - void testCustomizeUndertowSocketOption() { - bind("server.undertow.options.socket.ALWAYS_SET_KEEP_ALIVE", "true"); - assertThat(this.properties.getOptions().getSocket()).containsEntry("ALWAYS_SET_KEEP_ALIVE", "true"); - } - - @Test - void testCustomizeUndertowIoThreads() { - bind("server.undertow.threads.io", "4"); - assertThat(this.properties.getThreads().getIo()).isEqualTo(4); - } - - @Test - void testCustomizeUndertowWorkerThreads() { - bind("server.undertow.threads.worker", "10"); - assertThat(this.properties.getThreads().getWorker()).isEqualTo(10); - } - - @Test - void undertowMaxHttpPostSizeMatchesDefault() { - assertThat(this.properties.getMaxHttpPostSize().toBytes()).isEqualTo(UndertowOptions.DEFAULT_MAX_ENTITY_SIZE); - } - - private void bind(String name, String value) { - bind(Collections.singletonMap(name, value)); - } - - private void bind(Map map) { - ConfigurationPropertySource source = new MapConfigurationPropertySource(map); - new Binder(source).bind("server.undertow", Bindable.ofInstance(this.properties)); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java deleted file mode 100644 index faeacfbfc7b..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import io.undertow.UndertowOptions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.xnio.Option; -import org.xnio.OptionMap; -import org.xnio.Options; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.server.autoconfigure.ServerProperties; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.test.context.support.TestPropertySourceUtils; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.BDDMockito.willAnswer; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link UndertowWebServerFactoryCustomizer}. - * - * @author Brian Clozel - * @author Phillip Webb - * @author Artsiom Yudovin - * @author Rafiullah Hamedy - * @author HaiTao Zhang - */ -class UndertowWebServerFactoryCustomizerTests { - - private final MockEnvironment environment = new MockEnvironment(); - - private final ServerProperties serverProperties = new ServerProperties(); - - private final UndertowServerProperties undertowProperties = new UndertowServerProperties(); - - private UndertowWebServerFactoryCustomizer customizer; - - @BeforeEach - void setup() { - ConfigurationPropertySources.attach(this.environment); - this.customizer = new UndertowWebServerFactoryCustomizer(this.environment, this.serverProperties, - this.undertowProperties); - } - - @Test - void customizeUndertowAccessLog() { - bind("server.undertow.accesslog.enabled=true", "server.undertow.accesslog.pattern=foo", - "server.undertow.accesslog.prefix=test_log", "server.undertow.accesslog.suffix=txt", - "server.undertow.accesslog.dir=test-logs", "server.undertow.accesslog.rotate=false"); - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setAccessLogEnabled(true); - then(factory).should().setAccessLogPattern("foo"); - then(factory).should().setAccessLogPrefix("test_log"); - then(factory).should().setAccessLogSuffix("txt"); - then(factory).should().setAccessLogDirectory(new File("test-logs")); - then(factory).should().setAccessLogRotate(false); - } - - @Test - void customMaxHttpRequestHeaderSize() { - bind("server.max-http-request-header-size=2048"); - assertThat(boundServerOption(UndertowOptions.MAX_HEADER_SIZE)).isEqualTo(2048); - } - - @Test - void customMaxHttpRequestHeaderSizeIgnoredIfNegative() { - bind("server.max-http-request-header-size=-1"); - assertThat(boundServerOption(UndertowOptions.MAX_HEADER_SIZE)).isNull(); - } - - @Test - void customMaxHttpRequestHeaderSizeIgnoredIfZero() { - bind("server.max-http-request-header-size=0"); - assertThat(boundServerOption(UndertowOptions.MAX_HEADER_SIZE)).isNull(); - } - - @Test - void customMaxHttpPostSize() { - bind("server.undertow.max-http-post-size=256"); - assertThat(boundServerOption(UndertowOptions.MAX_ENTITY_SIZE)).isEqualTo(256); - } - - @Test - void customConnectionTimeout() { - bind("server.undertow.no-request-timeout=1m"); - assertThat(boundServerOption(UndertowOptions.NO_REQUEST_TIMEOUT)).isEqualTo(60000); - } - - @Test - void customMaxParameters() { - bind("server.undertow.max-parameters=4"); - assertThat(boundServerOption(UndertowOptions.MAX_PARAMETERS)).isEqualTo(4); - } - - @Test - void customMaxHeaders() { - bind("server.undertow.max-headers=4"); - assertThat(boundServerOption(UndertowOptions.MAX_HEADERS)).isEqualTo(4); - } - - @Test - void customMaxCookies() { - bind("server.undertow.max-cookies=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); - then(factory).should().setIoThreads(4); - } - - @Test - void customizeWorkerThreads() { - bind("server.undertow.threads.worker=10"); - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setWorkerThreads(10); - } - - @Test - void enableSlashDecoding() { - bind("server.undertow.decode-slash=true"); - assertThat(boundServerOption(UndertowOptions.DECODE_SLASH)).isTrue(); - } - - @Test - void disableUrlDecoding() { - bind("server.undertow.decode-url=false"); - assertThat(boundServerOption(UndertowOptions.DECODE_URL)).isFalse(); - } - - @Test - void customUrlCharset() { - bind("server.undertow.url-charset=UTF-16"); - assertThat(boundServerOption(UndertowOptions.URL_CHARSET)).isEqualTo(StandardCharsets.UTF_16.name()); - } - - @Test - void disableAlwaysSetKeepAlive() { - bind("server.undertow.always-set-keep-alive=false"); - assertThat(boundServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)).isFalse(); - } - - @Test - void customServerOption() { - bind("server.undertow.options.server.ALWAYS_SET_KEEP_ALIVE=false"); - assertThat(boundServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)).isFalse(); - } - - @Test - void customServerOptionShouldBeRelaxed() { - bind("server.undertow.options.server.always-set-keep-alive=false"); - assertThat(boundServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)).isFalse(); - } - - @Test - void customSocketOption() { - bind("server.undertow.options.socket.CONNECTION_LOW_WATER=8"); - assertThat(boundSocketOption(Options.CONNECTION_LOW_WATER)).isEqualTo(8); - } - - @Test - void customSocketOptionShouldBeRelaxed() { - bind("server.undertow.options.socket.connection-low-water=8"); - assertThat(boundSocketOption(Options.CONNECTION_LOW_WATER)).isEqualTo(8); - } - - @Test - void deduceUseForwardHeaders() { - this.environment.setProperty("DYNO", "-"); - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(true); - } - - @Test - void defaultUseForwardHeaders() { - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(false); - } - - @Test - void forwardHeadersWhenStrategyIsNativeShouldConfigureValve() { - this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NATIVE); - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(true); - } - - @Test - void forwardHeadersWhenStrategyIsNoneShouldNotConfigureValve() { - this.environment.setProperty("DYNO", "-"); - this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NONE); - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(false); - } - - private T boundServerOption(Option option) { - Builder builder = Undertow.builder(); - ConfigurableUndertowWebServerFactory factory = mockFactory(builder); - this.customizer.customize(factory); - OptionMap map = ((OptionMap.Builder) ReflectionTestUtils.getField(builder, "serverOptions")).getMap(); - return map.get(option); - } - - private T boundSocketOption(Option option) { - Builder builder = Undertow.builder(); - ConfigurableUndertowWebServerFactory factory = mockFactory(builder); - this.customizer.customize(factory); - OptionMap map = ((OptionMap.Builder) ReflectionTestUtils.getField(builder, "socketOptions")).getMap(); - return map.get(option); - } - - private ConfigurableUndertowWebServerFactory mockFactory(Builder builder) { - ConfigurableUndertowWebServerFactory factory = mock(ConfigurableUndertowWebServerFactory.class); - willAnswer((invocation) -> { - Object argument = invocation.getArgument(0); - Arrays.stream((argument instanceof UndertowBuilderCustomizer undertowCustomizer) - ? new UndertowBuilderCustomizer[] { undertowCustomizer } : (UndertowBuilderCustomizer[]) argument) - .forEach((customizer) -> customizer.customize(builder)); - return null; - }).given(factory).addBuilderCustomizers(any()); - return factory; - } - - private void bind(String... inlinedProperties) { - TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties); - Binder binder = new Binder(ConfigurationPropertySources.get(this.environment)); - binder.bind("server", Bindable.ofInstance(this.serverProperties)); - binder.bind("server.undertow", Bindable.ofInstance(this.undertowProperties)); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java deleted file mode 100644 index ff93af6b575..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.actuate.web; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.undertow.autoconfigure.actuate.web.server.UndertowManagementServerProperties; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowManagementServerProperties}. - * - * @author Andy Wilkinson - */ -class UndertowManagementServerPropertiesTests { - - @Test - void accessLogsArePrefixedByDefault() { - UndertowManagementServerProperties properties = new UndertowManagementServerProperties(); - assertThat(properties.getAccesslog().getPrefix()).isEqualTo("management_"); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java deleted file mode 100644 index 28367095253..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.reactive; - -import io.undertow.Undertow.Builder; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; -import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.server.autoconfigure.reactive.AbstractReactiveWebServerAutoConfigurationTests; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link UndertowReactiveWebServerAutoConfiguration}. - * - * @author Brian Clozel - * @author Raheela Aslam - * @author Madhura Bhave - * @author Scott Frederick - */ -class UndertowReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests { - - UndertowReactiveWebServerAutoConfigurationTests() { - super(UndertowReactiveWebServerAutoConfiguration.class); - } - - @Test - void undertowBuilderCustomizerBeanIsAddedToFactory() { - this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class).run((context) -> { - UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); - assertThat(factory.getBuilderCustomizers()) - .contains(context.getBean("builderCustomizer", UndertowBuilderCustomizer.class)); - }); - } - - @Test - void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - this.serverRunner.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class) - .run((context) -> { - UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); - UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", - UndertowBuilderCustomizer.class); - assertThat(factory.getBuilderCustomizers()).contains(customizer); - then(customizer).should().customize(any(Builder.class)); - }); - } - - @Configuration(proxyBeanMethods = false) - static class UndertowBuilderCustomizerConfiguration { - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return (builder) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { - - private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addBuilderCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowDeploymentInfoCustomizerConfiguration { - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return (deploymentInfo) -> { - }; - } - - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java deleted file mode 100644 index c4ac22794c7..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import io.undertow.Undertow.Builder; -import io.undertow.servlet.api.DeploymentInfo; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.server.autoconfigure.servlet.AbstractServletWebServerAutoConfigurationTests; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link UndertowServletWebServerAutoConfiguration}. - * - * @author Dave Syer - * @author Phillip Webb - * @author Stephane Nicoll - * @author Raheela Aslam - * @author Madhura Bhave - */ -class UndertowServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests { - - UndertowServletWebServerAutoConfigurationTests() { - super(UndertowServletWebServerAutoConfiguration.class); - } - - @Test - void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() { - this.serverRunner.withUserConfiguration(UndertowDeploymentInfoCustomizerConfiguration.class).run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer", - UndertowDeploymentInfoCustomizer.class); - assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer); - }); - } - - @Test - void undertowDeploymentInfoCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - this.serverRunner.withUserConfiguration(DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration.class) - .run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer", - UndertowDeploymentInfoCustomizer.class); - assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer); - then(customizer).should().customize(any(DeploymentInfo.class)); - }); - } - - @Test - void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - this.serverRunner.withConfiguration(AutoConfigurations.of(UndertowServletWebServerAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class) - .run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", - UndertowBuilderCustomizer.class); - assertThat(factory.getBuilderCustomizers()).contains(customizer); - then(customizer).should().customize(any(Builder.class)); - }); - } - - @Test - void undertowBuilderCustomizerBeanIsAddedToFactory() { - this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class).run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - assertThat(factory.getBuilderCustomizers()) - .contains(context.getBean("builderCustomizer", UndertowBuilderCustomizer.class)); - }); - } - - @Test - void undertowServletWebServerFactoryCustomizerIsAutoConfigured() { - this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(UndertowServletWebServerFactoryCustomizer.class)); - } - - @Configuration(proxyBeanMethods = false) - static class UndertowBuilderCustomizerConfiguration { - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return (builder) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { - - private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addBuilderCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowDeploymentInfoCustomizerConfiguration { - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return (deploymentInfo) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration { - - private final UndertowDeploymentInfoCustomizer customizer = mock(UndertowDeploymentInfoCustomizer.class); - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addDeploymentInfoCustomizers(this.customizer); - } - - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java deleted file mode 100644 index 1925ff6ea02..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowServletWebServerFactoryCustomizer} - * - * @author Andy Wilkinson - */ -class UndertowServletWebServerFactoryCustomizerTests { - - @Test - void eagerFilterInitCanBeDisabled() { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); - assertThat(factory.isEagerFilterInit()).isTrue(); - UndertowServerProperties undertowProperties = new UndertowServerProperties(); - undertowProperties.setEagerFilterInit(false); - new UndertowServletWebServerFactoryCustomizer(undertowProperties).customize(factory); - assertThat(factory.isEagerFilterInit()).isFalse(); - } - - @Test - void preservePathOnForwardCanBeEnabled() { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); - assertThat(factory.isPreservePathOnForward()).isFalse(); - UndertowServerProperties undertowProperties = new UndertowServerProperties(); - undertowProperties.setPreservePathOnForward(true); - new UndertowServletWebServerFactoryCustomizer(undertowProperties).customize(factory); - assertThat(factory.isPreservePathOnForward()).isTrue(); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java deleted file mode 100644 index b1f94856b81..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.autoconfigure.servlet; - -import jakarta.servlet.ServletContextListener; - -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.servlet.AbstractServletWebServerServletContextListenerTests; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Tests for Undertow driving {@link ServletContextListener}s correctly. - * - * @author Andy Wilkinson - */ -class UndertowServletWebServerServletContextListenerTests extends AbstractServletWebServerServletContextListenerTests { - - UndertowServletWebServerServletContextListenerTests() { - super(UndertowConfiguration.class); - } - - @Configuration(proxyBeanMethods = false) - static class UndertowConfiguration { - - @Bean - UndertowServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(0); - } - - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java deleted file mode 100644 index c69edebcdf1..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.reactive; - -import java.io.File; -import java.time.Duration; -import java.util.Arrays; - -import io.undertow.Undertow; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.mockito.InOrder; -import reactor.core.publisher.Mono; - -import org.springframework.boot.undertow.UndertowAccess; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.undertow.UndertowWebServer; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; -import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; -import org.springframework.http.MediaType; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClientResponseException.ServiceUnavailable; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.hamcrest.Matchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link UndertowReactiveWebServerFactory} and {@link UndertowWebServer}. - * - * @author Brian Clozel - * @author Madhura Bhave - */ -class UndertowReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactoryTests { - - @TempDir - File tempDir; - - @Override - protected UndertowReactiveWebServerFactory getFactory() { - return new UndertowReactiveWebServerFactory(0); - } - - @Test - void setNullBuilderCustomizersShouldThrowException() { - UndertowReactiveWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setBuilderCustomizers(null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void addNullBuilderCustomizersShouldThrowException() { - UndertowReactiveWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException() - .isThrownBy(() -> factory.addBuilderCustomizers((UndertowBuilderCustomizer[]) null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void builderCustomizersShouldBeInvoked() { - UndertowReactiveWebServerFactory factory = getFactory(); - HttpHandler handler = mock(HttpHandler.class); - UndertowBuilderCustomizer[] customizers = new UndertowBuilderCustomizer[4]; - Arrays.setAll(customizers, (i) -> mock(UndertowBuilderCustomizer.class)); - factory.setBuilderCustomizers(Arrays.asList(customizers[0], customizers[1])); - factory.addBuilderCustomizers(customizers[2], customizers[3]); - this.webServer = factory.getWebServer(handler); - InOrder ordered = inOrder((Object[]) customizers); - for (UndertowBuilderCustomizer customizer : customizers) { - ordered.verify(customizer).customize(any(Undertow.Builder.class)); - } - } - - @Test - void useForwardedHeaders() { - UndertowReactiveWebServerFactory factory = getFactory(); - factory.setUseForwardHeaders(true); - assertForwardHeaderIsUsed(factory); - } - - @Test - void accessLogCanBeEnabled() { - testAccessLog(null, null, "access_log.log"); - } - - @Test - void accessLogCanBeCustomized() { - testAccessLog("my_access.", "logz", "my_access.logz"); - } - - @Test - void whenServerIsShuttingDownGracefullyThenNewConnectionsAreRejectedWithServiceUnavailable() { - UndertowReactiveWebServerFactory factory = getFactory(); - factory.setShutdown(Shutdown.GRACEFUL); - BlockingHandler blockingHandler = new BlockingHandler(); - this.webServer = factory.getWebServer(blockingHandler); - this.webServer.start(); - this.webServer.shutDownGracefully((result) -> { - }); - WebClient webClient = getWebClient(this.webServer.getPort()).build(); - Awaitility.await().atMost(Duration.ofSeconds(30)).until(() -> { - blockingHandler.stopBlocking(); - try { - webClient.get().retrieve().toBodilessEntity().block(); - return false; - } - catch (RuntimeException ex) { - return ex instanceof ServiceUnavailable; - } - }); - this.webServer.stop(); - } - - private void testAccessLog(String prefix, String suffix, String expectedFile) { - UndertowReactiveWebServerFactory factory = getFactory(); - factory.setAccessLogEnabled(true); - factory.setAccessLogPrefix(prefix); - factory.setAccessLogSuffix(suffix); - File accessLogDirectory = this.tempDir; - factory.setAccessLogDirectory(accessLogDirectory); - assertThat(accessLogDirectory).isEmptyDirectory(); - this.webServer = factory.getWebServer(new EchoHandler()); - this.webServer.start(); - WebClient client = getWebClient(this.webServer.getPort()).build(); - Mono result = client.post() - .uri("/test") - .contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromValue("Hello World")) - .retrieve() - .bodyToMono(String.class); - assertThat(result.block(Duration.ofSeconds(30))).isEqualTo("Hello World"); - File accessLog = new File(accessLogDirectory, expectedFile); - awaitFile(accessLog); - assertThat(accessLogDirectory.listFiles()).contains(accessLog); - } - - private void awaitFile(File file) { - Awaitility.waitAtMost(Duration.ofSeconds(10)).until(file::exists, is(true)); - } - - @Override - protected String startedLogMessage() { - return UndertowAccess.getStartedLogMessage((UndertowWebServer) this.webServer); - } - - @Override - protected void addConnector(int port, ConfigurableReactiveWebServerFactory factory) { - ((UndertowReactiveWebServerFactory) factory) - .addBuilderCustomizers((builder) -> builder.addHttpListener(port, "0.0.0.0")); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java deleted file mode 100644 index dda0be4d9c1..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; - -import io.undertow.servlet.api.SessionPersistenceManager.PersistentSession; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link FileSessionPersistence}. - * - * @author Phillip Webb - */ -class FileSessionPersistenceTests { - - private File dir; - - private FileSessionPersistence persistence; - - private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - - private final Date expiration = new Date(System.currentTimeMillis() + 10000); - - @BeforeEach - void setup(@TempDir File tempDir) { - this.dir = tempDir; - this.dir.mkdir(); - this.persistence = new FileSessionPersistence(this.dir); - } - - @Test - void loadsNullForMissingFile() { - Map attributes = this.persistence.loadSessionAttributes("test", this.classLoader); - assertThat(attributes).isNull(); - } - - @Test - void persistAndLoad() { - Map sessionData = new LinkedHashMap<>(); - Map data = new LinkedHashMap<>(); - data.put("spring", "boot"); - PersistentSession session = new PersistentSession(this.expiration, data); - sessionData.put("abc", session); - this.persistence.persistSessions("test", sessionData); - Map restored = this.persistence.loadSessionAttributes("test", this.classLoader); - assertThat(restored).isNotNull(); - assertThat(restored.get("abc").getExpiration()).isEqualTo(this.expiration); - assertThat(restored.get("abc").getSessionData()).containsEntry("spring", "boot"); - } - - @Test - void dontRestoreExpired() { - Date expired = new Date(System.currentTimeMillis() - 1000); - Map sessionData = new LinkedHashMap<>(); - Map data = new LinkedHashMap<>(); - data.put("spring", "boot"); - PersistentSession session = new PersistentSession(expired, data); - sessionData.put("abc", session); - this.persistence.persistSessions("test", sessionData); - Map restored = this.persistence.loadSessionAttributes("test", this.classLoader); - assertThat(restored).isNotNull(); - assertThat(restored).doesNotContainKey("abc"); - } - - @Test - void deleteFileOnClear() { - File sessionFile = new File(this.dir, "test.session"); - Map sessionData = new LinkedHashMap<>(); - this.persistence.persistSessions("test", sessionData); - assertThat(sessionFile).exists(); - this.persistence.clear("test"); - assertThat(sessionFile).doesNotExist(); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java deleted file mode 100644 index d2d4e8c3cc8..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Arrays; -import java.util.List; -import java.util.jar.JarOutputStream; -import java.util.zip.ZipEntry; - -import io.undertow.server.handlers.resource.Resource; -import io.undertow.server.handlers.resource.ResourceManager; -import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import org.springframework.util.FileCopyUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JarResourceManager}. - * - * @author Andy Wilkinson - */ -class JarResourceManagerTests { - - @TempDir - static File tempDir; - - @ResourceManagersTest - void emptyPathIsHandledCorrectly(String filename, ResourceManager resourceManager) throws IOException { - Resource resource = resourceManager.getResource(""); - assertThat(resource).isNotNull(); - assertThat(resource.isDirectory()).isTrue(); - } - - @ResourceManagersTest - void rootPathIsHandledCorrectly(String filename, ResourceManager resourceManager) throws IOException { - Resource resource = resourceManager.getResource("/"); - assertThat(resource).isNotNull(); - assertThat(resource.isDirectory()).isTrue(); - } - - @ResourceManagersTest - void resourceIsFoundInJarFile(String filename, ResourceManager resourceManager) throws IOException { - Resource resource = resourceManager.getResource("/hello.txt"); - assertThat(resource).isNotNull(); - assertThat(resource.isDirectory()).isFalse(); - assertThat(resource.getContentLength()).isEqualTo(5); - } - - @ResourceManagersTest - void resourceIsFoundInJarFileWithoutLeadingSlash(String filename, ResourceManager resourceManager) - throws IOException { - Resource resource = resourceManager.getResource("hello.txt"); - assertThat(resource).isNotNull(); - assertThat(resource.isDirectory()).isFalse(); - assertThat(resource.getContentLength()).isEqualTo(5); - } - - static List resourceManagers() throws IOException { - File jar = new File(tempDir, "test.jar"); - try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar))) { - out.putNextEntry(new ZipEntry("hello.txt")); - out.write("hello".getBytes()); - } - File troublesomeNameJar = new File(tempDir, "test##1.0.jar"); - FileCopyUtils.copy(jar, troublesomeNameJar); - return Arrays.asList(Arguments.of(jar.getName(), new JarResourceManager(jar)), - Arguments.of(troublesomeNameJar.getName(), new JarResourceManager(troublesomeNameJar))); - } - - @ParameterizedTest(name = "[{index}] {0}") - @MethodSource("resourceManagers") - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - private @interface ResourceManagersTest { - - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java deleted file mode 100644 index b83597873c3..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import java.io.File; -import java.io.IOException; -import java.net.SocketException; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.time.Duration; -import java.util.Arrays; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicReference; - -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLHandshakeException; - -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.servlet.api.ServletContainer; -import jakarta.servlet.ServletRegistration.Dynamic; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.core5.http.HttpResponse; -import org.apache.jasper.servlet.JspServlet; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledForJreRange; -import org.junit.jupiter.api.condition.JRE; -import org.mockito.InOrder; - -import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.testsupport.web.servlet.ExampleServlet; -import org.springframework.boot.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.error.ErrorPage; -import org.springframework.boot.web.server.GracefulShutdownResult; -import org.springframework.boot.web.server.PortInUseException; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.servlet.AbstractServletWebServerFactoryTests; -import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIOException; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.hamcrest.Matchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link UndertowServletWebServerFactory}. - * - * @author Ivan Sopov - * @author Andy Wilkinson - */ -class UndertowServletWebServerFactoryTests extends AbstractServletWebServerFactoryTests { - - @Override - protected UndertowServletWebServerFactory getFactory() { - return new UndertowServletWebServerFactory(0); - } - - @AfterEach - void awaitClosureOfSslRelatedInputStreams() { - // https://issues.redhat.com/browse/UNDERTOW-1705 - File resource = new File(this.tempDir, "test.txt"); - Awaitility.await().atMost(Duration.ofSeconds(30)).until(() -> (!resource.isFile()) || resource.delete()); - } - - @Test - void errorPage404() throws Exception { - ConfigurableServletWebServerFactory factory = getFactory(); - factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello")); - this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(), "/hello")); - this.webServer.start(); - assertThat(getResponse(getLocalUrl("/hello"))).isEqualTo("Hello World"); - assertThat(getResponse(getLocalUrl("/not-found"))).isEqualTo("Hello World"); - } - - @Test - void setNullBuilderCustomizersThrows() { - UndertowServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setBuilderCustomizers(null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void addNullAddBuilderCustomizersThrows() { - UndertowServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException() - .isThrownBy(() -> factory.addBuilderCustomizers((UndertowBuilderCustomizer[]) null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void builderCustomizers() { - UndertowServletWebServerFactory factory = getFactory(); - UndertowBuilderCustomizer[] customizers = new UndertowBuilderCustomizer[4]; - Arrays.setAll(customizers, (i) -> mock(UndertowBuilderCustomizer.class)); - factory.setBuilderCustomizers(Arrays.asList(customizers[0], customizers[1])); - factory.addBuilderCustomizers(customizers[2], customizers[3]); - this.webServer = factory.getWebServer(); - InOrder ordered = inOrder((Object[]) customizers); - for (UndertowBuilderCustomizer customizer : customizers) { - ordered.verify(customizer).customize(any(Builder.class)); - } - } - - @Test - void setNullDeploymentInfoCustomizersThrows() { - UndertowServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setDeploymentInfoCustomizers(null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void addNullAddDeploymentInfoCustomizersThrows() { - UndertowServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException() - .isThrownBy(() -> factory.addDeploymentInfoCustomizers((UndertowDeploymentInfoCustomizer[]) null)) - .withMessageContaining("'customizers' must not be null"); - } - - @Test - void deploymentInfo() { - UndertowServletWebServerFactory factory = getFactory(); - UndertowDeploymentInfoCustomizer[] customizers = new UndertowDeploymentInfoCustomizer[4]; - Arrays.setAll(customizers, (i) -> mock(UndertowDeploymentInfoCustomizer.class)); - factory.setDeploymentInfoCustomizers(Arrays.asList(customizers[0], customizers[1])); - factory.addDeploymentInfoCustomizers(customizers[2], customizers[3]); - this.webServer = factory.getWebServer(); - InOrder ordered = inOrder((Object[]) customizers); - for (UndertowDeploymentInfoCustomizer customizer : customizers) { - ordered.verify(customizer).customize(any(DeploymentInfo.class)); - } - } - - @Test - @WithPackageResources("test.jks") - void basicSslClasspathKeyStore() throws Exception { - testBasicSslWithKeyStore("classpath:test.jks"); - } - - @Test - void defaultContextPath() { - UndertowServletWebServerFactory factory = getFactory(); - final AtomicReference contextPath = new AtomicReference<>(); - factory.addDeploymentInfoCustomizers((deploymentInfo) -> contextPath.set(deploymentInfo.getContextPath())); - this.webServer = factory.getWebServer(); - assertThat(contextPath.get()).isEqualTo("/"); - } - - @Test - void useForwardHeaders() throws Exception { - UndertowServletWebServerFactory factory = getFactory(); - factory.setUseForwardHeaders(true); - assertForwardHeaderIsUsed(factory); - } - - @Test - void eachFactoryUsesADiscreteServletContainer() { - assertThat(getServletContainerFromNewFactory()).isNotEqualTo(getServletContainerFromNewFactory()); - } - - @Test - void accessLogCanBeEnabled() throws IOException, URISyntaxException { - testAccessLog(null, null, "access_log.log"); - } - - @Test - void accessLogCanBeCustomized() throws IOException, URISyntaxException { - testAccessLog("my_access.", "logz", "my_access.logz"); - } - - @Test - void whenServerIsShuttingDownGracefullyThenRequestsAreRejectedWithServiceUnavailable() throws Exception { - ConfigurableServletWebServerFactory factory = getFactory(); - factory.setShutdown(Shutdown.GRACEFUL); - BlockingServlet blockingServlet = new BlockingServlet(); - this.webServer = factory.getWebServer((context) -> { - Dynamic registration = context.addServlet("blockingServlet", blockingServlet); - registration.addMapping("/blocking"); - registration.setAsyncSupported(true); - }); - this.webServer.start(); - int port = this.webServer.getPort(); - Future request = initiateGetRequest(port, "/blocking"); - blockingServlet.awaitQueue(); - AtomicReference result = new AtomicReference<>(); - this.webServer.shutDownGracefully(result::set); - assertThat(result.get()).isNull(); - blockingServlet.admitOne(); - assertThat(request.get()).isInstanceOf(HttpResponse.class); - Object rejectedResult = initiateGetRequest(port, "/").get(); - assertThat(rejectedResult).isInstanceOf(HttpResponse.class); - assertThat(((HttpResponse) rejectedResult).getCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE.value()); - this.webServer.stop(); - } - - @Test - void whenServerIsShuttingDownARequestOnAnIdleConnectionAreRejectedWithServiceUnavailable() throws Exception { - ConfigurableServletWebServerFactory factory = getFactory(); - factory.setShutdown(Shutdown.GRACEFUL); - BlockingServlet blockingServlet = new BlockingServlet(); - this.webServer = factory.getWebServer((context) -> { - Dynamic registration = context.addServlet("blockingServlet", blockingServlet); - registration.addMapping("/blocking"); - registration.setAsyncSupported(true); - }); - HttpClient httpClient = HttpClients.createMinimal(); - this.webServer.start(); - int port = this.webServer.getPort(); - Future keepAliveRequest = initiateGetRequest(httpClient, port, "/blocking"); - blockingServlet.awaitQueue(); - blockingServlet.admitOne(); - assertThat(keepAliveRequest.get()).isInstanceOf(HttpResponse.class); - Future request = initiateGetRequest(port, "/blocking"); - blockingServlet.awaitQueue(); - this.webServer.shutDownGracefully((result) -> { - }); - HttpResponse idleConnectionResponse = (HttpResponse) initiateGetRequest(httpClient, port, "/").get(); - assertThat(idleConnectionResponse.getCode()).isEqualTo(503); - blockingServlet.admitOne(); - Object response = request.get(); - assertThat(response).isInstanceOf(HttpResponse.class); - this.webServer.stop(); - } - - @Test - @Override - @Disabled("https://issues.redhat.com/browse/UNDERTOW-2420") - protected void portClashOfSecondaryConnectorResultsInPortInUseException() throws Exception { - super.portClashOfSecondaryConnectorResultsInPortInUseException(); - } - - @Test - @Override - @Disabled("Restart after stop is not supported with Undertow") - protected void restartAfterStop() { - } - - @Test - @Override - @Disabled("Undertow's architecture prevents separating stop and destroy") - protected void servletContextListenerContextDestroyedIsNotCalledWhenContainerIsStopped() { - } - - private void testAccessLog(String prefix, String suffix, String expectedFile) - throws IOException, URISyntaxException { - UndertowServletWebServerFactory factory = getFactory(); - factory.setAccessLogEnabled(true); - factory.setAccessLogPrefix(prefix); - factory.setAccessLogSuffix(suffix); - File accessLogDirectory = this.tempDir; - factory.setAccessLogDirectory(accessLogDirectory); - assertThat(accessLogDirectory).isEmptyDirectory(); - this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(), "/hello")); - this.webServer.start(); - assertThat(getResponse(getLocalUrl("/hello"))).isEqualTo("Hello World"); - File accessLog = new File(accessLogDirectory, expectedFile); - awaitFile(accessLog); - assertThat(accessLogDirectory.listFiles()).contains(accessLog); - } - - @Override - protected void addConnector(int port, ConfigurableServletWebServerFactory factory) { - ((UndertowServletWebServerFactory) factory) - .addBuilderCustomizers((builder) -> builder.addHttpListener(port, "0.0.0.0")); - } - - @Test - @WithPackageResources("restricted.jks") - void sslRestrictedProtocolsEmptyCipherFailure() { - assertThatIOException() - .isThrownBy(() -> testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, - new String[] { "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" })) - .isInstanceOfAny(SSLException.class, SSLHandshakeException.class, SocketException.class); - } - - @Test - @WithPackageResources("restricted.jks") - void sslRestrictedProtocolsECDHETLS1Failure() { - assertThatIOException() - .isThrownBy(() -> testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1" }, - new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" })) - .isInstanceOfAny(SSLException.class, SocketException.class); - } - - @Test - @WithPackageResources("restricted.jks") - void sslRestrictedProtocolsECDHESuccess() throws Exception { - testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, - new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" }); - } - - @Test - @WithPackageResources("restricted.jks") - @DisabledForJreRange(min = JRE.JAVA_24) - void sslRestrictedProtocolsRSATLS12Success() throws Exception { - testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, - new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA256" }); - } - - @Test - @WithPackageResources("restricted.jks") - void sslRestrictedProtocolsRSATLS11Failure() { - assertThatIOException() - .isThrownBy(() -> testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.1" }, - new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA256" })) - .isInstanceOfAny(SSLException.class, SocketException.class); - } - - @Override - protected JspServlet getJspServlet() { - return null; // Undertow does not support JSPs - } - - private void awaitFile(File file) { - Awaitility.waitAtMost(Duration.ofSeconds(10)).until(file::exists, is(true)); - } - - private ServletContainer getServletContainerFromNewFactory() { - UndertowServletWebServer container = (UndertowServletWebServer) getFactory().getWebServer(); - try { - return container.getDeploymentManager().getDeployment().getServletContainer(); - } - finally { - container.stop(); - } - } - - @Override - protected Map getActualMimeMappings() { - return ((UndertowServletWebServer) this.webServer).getDeploymentManager() - .getDeployment() - .getMimeExtensionMappings(); - } - - @Override - protected Charset getCharset(Locale locale) { - DeploymentInfo info = ((UndertowServletWebServer) this.webServer).getDeploymentManager() - .getDeployment() - .getDeploymentInfo(); - String charsetName = info.getLocaleCharsetMapping().get(locale.toString()); - return (charsetName != null) ? Charset.forName(charsetName) : null; - } - - @Override - protected void handleExceptionCausedByBlockedPortOnPrimaryConnector(RuntimeException ex, int blockedPort) { - assertThat(ex).isInstanceOf(PortInUseException.class); - assertThat(((PortInUseException) ex).getPort()).isEqualTo(blockedPort); - Undertow undertow = (Undertow) ReflectionTestUtils.getField(this.webServer, "undertow"); - assertThat(undertow.getWorker()).isNull(); - } - - @Override - protected void handleExceptionCausedByBlockedPortOnSecondaryConnector(RuntimeException ex, int blockedPort) { - handleExceptionCausedByBlockedPortOnPrimaryConnector(ex, blockedPort); - } - - @Override - protected String startedLogMessage() { - return ((UndertowServletWebServer) this.webServer).getStartedLogMessage(); - } - - private void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, String[] ciphers) throws Exception { - ConfigurableServletWebServerFactory factory = getFactory(); - factory.setSsl(getSsl(null, "password", "classpath:restricted.jks", null, protocols, ciphers)); - this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(true, false), "/hello")); - this.webServer.start(); - HttpComponentsClientHttpRequestFactory requestFactory = createHttpComponentsRequestFactory( - createTrustSelfSignedTlsSocketStrategy()); - assertThat(getResponse(getLocalUrl("https", "/hello"), requestFactory)).contains("scheme=https"); - } - -} diff --git a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java b/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java deleted file mode 100644 index aca7f4dc54e..00000000000 --- a/module/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.undertow.servlet; - -import org.springframework.boot.undertow.UndertowWebServer; -import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Integration tests for {@link ServletWebServerApplicationContext} and - * {@link UndertowWebServer} running Spring MVC. - */ -class UndertowServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests { - - protected UndertowServletWebServerMvcIntegrationTests() { - super(UndertowConfig.class); - } - - @Configuration(proxyBeanMethods = false) - static class UndertowConfig { - - @Bean - UndertowServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(0); - } - - } - -} diff --git a/module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/restricted.jks b/module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/restricted.jks deleted file mode 100644 index 1bce90bba66f697b2051dc839377de1f016a563d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4464 zcmeH}XH-*rm&VgbCh{iXciaQlwArJNKQr?|9dmPc!r7e%R}r{d_oUujlOl@BbVu9xMU?01%_V zi~<6nH%adHwl^8C7q1-;u>b&=Ko|<-0K*Ptm4pHzKnc)MAdm?Fp+M%C-upfh)ig4F zk2bYO)$;1B`%75OLb$$2HP`<%SXBaZKo!5}*(whI7G^b7fiQX0ZEFcAyV55V&{n7* z)N#Kd?%G5-AH+ddk0nWL9{E z2h5ylj3uqD%lU(kF5nR19Ju@NL!fV8@PqpkPde|)WrP)Ja;z+^eqirct7L>@L|9@&m#H7JCS>bmZ) zJOy^2{M7xBuZopUjnkz}^bn6aRu=E3Hg;lO&;hgPv;Y-Uh@qoH>(u3pSV7t=VeL1W z`cejVD?6_t7gLzA!rdrLK~CB={K$_JEr!(P^g3*qPQEn1ajnDEU=x0XV5 zH=xA`0lB8y`!S+VqVgjboiW^f#D^S;U0KgR+G=R)z9Gw1sLCZ>6mag*D~4f^de@q7vO5#C+8iH3Nkg$+qG%6Z7+yQQrlc_vDYh*#+x2Z zx6+=5Cw4wu(z*z}teq5-<13ndAzmOyE?q^lI$fZMd1o!^DPnCva&X|J;y7J5>%iSu zAP!a7k-NG*qin9C5%xA;-GNE!8lEOESJLQpOvo$Vvl4R0x2l>-c=@r;(d^TDWM@F2 zJ5c9|T8(<3{h5p89etKfRGob*;kcLO4OAYVaABA6{Po7w$hDGIsz(q_GwZ4)x5Pt> z=+c2TF&cT>XSe6civdM&@y^(&Xo_pGM^xsvS1ghw^ZQ%>IyEnU-Sr z5G9wD4av5A;v`q32eD(hXpVUPXyH7nt3_bPl_>C9ue=MC3&3kQj@w5@UO7FM7I45e z{rH@<6F+mpOy3LtCs{E=z?@yfl*@%?y&-2D7YaECcXhIvZGNC|-0Zo7TPGCzW>{mZ z<%|56jVsim6`}O|mUA*=H_JNInMvx4sxE=_rJ)V|#4*aV7=pN4;pu4c{ZC38#F`V0 z(10rw9|pGZ!p}P1?hG_3o9S-i{oW?rL=-r_a=t`>TA@b`d3^$Ss~ zG6<>vAS08xj66n(!O36@1?-QZfb5@uK|l})Vjh!C!@!{|5)p)mEjSR!#st84U^yAc z1e-vhTrd+4R}Yf!e=5wsD6n4?)?XC1|5A=&IDh{#n2W`YWN+(sjpTh3gF?cwau`LN z92Sek%gbB--eNI0+#l`#`8*V$;GZpF+!$aAkOP3B09ip4AQ13y6CG?&Ipx&a9JqW7 zcgH22yOMKr`9xCb#gy)oc?I2=Z&+a0P|^n^bxbk*?CrZFs)@4-Q5na$)Pvar1g)MM zqsw^FSCM;@A-mx~GE{G!U|yha<5=aM<9FN@8U^1ce%D^n*A*liqKH>Umg;7i62NSz zAJ}L&QK_m)waA)eZL#yKQE0CF?2#qBD=Mn39lJ*YG-B_Z+p<-4Qs>HjkZ7%I^VN%rMZ=b%`YaP4A&nlSsfg-kn zzRk9LKE*GCJ_0Cs`w`%zt`3LO9dwJxOrz3TY&{}+&IKSa5CF_Mjp4_fV*JZf><}IZ zf?A7@om+j^-z$Xo_xBBe8fvtJ|Jg*wUNKAr0^;IX&U{$f{2bnLLCANOps-Z6oSm@& zQ!`XibtykDi@8BpJ-*dK`jSAzXBSTCya-m>JWX}vb<)IjI^%X`3k=m4W?lC}990B^ zkzP&Hdj?k>la9=rJc{1yF&##-f!cM3*k4@!Ij!*SYM@H5!WnGnoK(!-*Hm6)kj8Cy zgOLlh$Ubu)Vu@5yyw`~aOME%`vqbp&#HY?t4nY$^G`~6{TxSJurci;UHIsJ|xxF<9 zVDyGn@w4Gpocv6SRJ4Fycbg|b2pR(U?L6}9JA909tcAl}ttJyG+k?CN7v5bLzD$~I z8%ljM^e5v}{v~9kNDIf*NFhN%+;O)id5AG26+)Eagan2Z0?I*2MM+n~qXL z=!MY=?+UzOk-u=F0{I}JrdfQLRx^ikLrKb))OyojuX}P zeO$o%GwqnDLxdtJT4ib$QKOK|rJcN%|AvqVEP7r(k*icnCE#g~OA*}}bxJW843x6w zX5>@okNE)=2RJ$Ek6U(#K6J5ge`bD=%NI@fc>VOgX*6?8k+MPZ)6Z&_)EcYddV%C~ znk7EYru$;;waVMo{6Afcg2Q$B3qNjIDz%-BQGLv!iEtd2f43o_Wn6T_z7FquL2=wh zW5l6V>umC}=6?J36jdtCUR)Aj@EGx~kt1@bidL4D5-Bqv^K63#yP+;(`^ZT3 zTushWK^f(qnDpSe=;1KaMUBbPyQ8#qks1EmGbw>s-aAQkHqp0+G;gHTaYoL);)&Rn=L17GVcH$vm1~zYF|9~6x zPjLIE#{3r=>@PIdztGtJLi+`viWpfe28)+f`VW9AViYj=KidDt$tXZ7W2>e9X%mpq z@Po)?z<%%*@+qHV;+MyDGGrE}zil3+URGJw1T>)3Lf#pPT-UNbFKD!Dp&DbpQ$ydV z#B8>wo45^;l|xR+k=C4SsIF;-&!1&weTVpS3f3FYUJe~loA`bzn|*7_%jM>P?1pak z(NPT`d1Ee1o_O4*&yPY$+aZbNH9;_MW)A__4B`f)*cd+GMzeLiO{kz`&xf(Cn4jGE zeYCB~C*gzXs$=a{1^=c{ZdT!!SVY@7J4e|z(_>SGQJjq|%wjA1EevKnVVvZUQX-Eh z`n#SO4;QtI1sC0tJE_8RC(1Y=Mrl5#h6U?@ATHbDT*X|BbNV((LYIUAb z+`YWe@kz_CS82i`WSGiKPL*; z?653ALWG<8a#xpD&ho-{58dd?T{VXquZ$o&`EzZsoZ}*Q*@DNV*Fw!|+qyDFy7=?$ zx=?Lp|BdfI_2P;X3H_gz@x<(2DL{ItbI9?3S${AFfRP3vEbbJZA86MFPj%7XU|C=R zFIm#5472YJSR$?0MWFH4-Y>3=po`dfw(S__3j|wY8N}TkN5SB3f&Rs-^bOG?ZFmS7NK3T3aeDe?O zAP7VcpyJpH%awavkxaDo=c06?wwZvy6A%E>Rptbeo|eWGOv?%~HIZRO!hidqV`V_& zT%E7G6WyF~G6*EgZ$T(4Jr?Kc&adI>?JmQ7ywGusftA(_S{~0*JN^A0acK`f~ zhLzsc-4W;N0YU&Y z;Xq~pG91VN3I_rK^%hFNu#-#uchOu0C81Yb1T$PF^G9e`u9?bJUu$OJQlq5tPF`o{ zC3MUU2pEf8zgeJuRSUD9YS`S)+l=JqiT0y?MvJPeTH!L9x9PNINX*lr6)fObjirmd zd20m0)h4Qz*qk{G=v32|qDC&WOEAyiaRA;`y6=M~8k3eqA7)Or`i(wOJzbF}=bgRI zSou~_x|~%4tmb~b?MY3tZSY9NMb%(tRMQYE?kk5?vW<2$j~?2>GqVDJCf+{Bu3AvA z=3V?q32>@J$gZc%y73(BD^q|rBX?(;j2_V~hd7hrHM^@0KOGoHpWLBoEQt8({;~@j z4UA8Gg$@@<0?_~gz&s-)26^guw@<;qC&6rH87)h$y*5_LS%c_Xn}OJSYu1mE62DEu z!NN$P@ISXZn&r4%|2lxt;E>~9{cFjOd+@mAKmdcblT_+MejJ`A$v0+V|&vU(Knyb-_UPUUok+VWdi<6$iGN~_!v|7168uQZBsX`dnWFp zDj6`y6FoFx6I>ToAswf;V_Y~?Nq6bB3`_6XfGjljNyaHeIK8`YGhG83nLX}{Hb2Yd zz#djXZKPex6<#SGMt^6f?v4>hF`wzw^Y+-Gk*|jex{Y$m*)Qh1_5JF#AbIPF+*luV zF>x~Ol6MD>RPur6^;*ajzgCec+%b+ayO<2mYN-0sv-6DHI`;0dT!{+@CeSiZVZ`7( zGP5=W52Sw`!}$5L%#=z}woIm>NHA0>)2rF{Z?`YYSPsvr6k4f4fQCT&8K-G#$sG3%A< zxpZ^Yx|?;wAs(V;g8f$U@@KBSnH6bmF_*Tu?6=#l^O?Z1?15TkytxuZeyi2nY8n5w zcK|K*kU!CUj)PZ-&~XhnPuS!sJqsSkExz4~5pcG3W9p`12!IH88KK5M7R zF_|OSdqiqM&A+{6K5$-t6?x?KAsQR)$WXZ$IcvxJnW&0=#9A;N*A(#wf z`aCKNX^n1;2%8WdTH{SiQ2+d`6kINwK<`kjAAPX6EukBSw;q@`iH1A*49{4ZY@UB{ znLS`>`G>$>K@Hl3)G5#cU7U=mHLPl#8`L}3A#g{rb}%?4p&aujNXtvt^F_5Y=i+T2 zRg&wtg_!|amO4}fi+Ad(@n&#Jw*R(FDP3z;(%iBaV3r8uW;`ObW;^+E3w{<_fK8;f za9AoE&u~~a&MRm=y(zM4%5pf-T+yr7@Bs1pMuC*xOp)k1HaR2lG)+5|tG6@&ubI0= z=IDHHS5kuIyAXfv&`y%C*dKQfNtCBOD|@fvJI%tAJ-kD0i=PIp=jLWi=Ld@QRFmXQ zd=k*Dhc!B=n>}o^gEi(deUV*Jr=}8h{LEb?%BYxAl$%u58C6dyover7MTgJugn4qO zreCn}PMMxNm6vG<$a=lgAqG#%=Xow)46?7qZ(6-rkTYl}+{XOf* zPMOGrjG6*Pu*yC$H%)x7+6E?8*#8RQMT+rBn&UCAT;wqW0HJCbZhGS%zuKnr3bZiL zo-fq&0&P?0-h6ne{7i(R)4J`{E)xn24~JjyKXA(T$nA$&VaaM`J>;y!qL-OZHL~V} zI`h-c5Tjxr_+%?Gan{@u?Xtoq)n(GJE$9Wm+_s79qJO7x>t^iPV)q&v^GU7d6rFX< z0>-Jf?Xt@QZtZ=FjA_{^g1X_F*uJs+hbrVZ=j99O0!w<_UecBBZ|X0;3eWYhq8S>3 z^BHZQLkf6Mo*;$-qY4Cx%Hu8w2r;6aK|7^J4n1UZ0)g4T$I@<+v~?f;ia$%WE4gc1 z;xeN)U-a8}S;>y0p`eO^Mv{Dcs%diRw;Rv5`za|?yQ!ZW@iH!$Y{w3}AvE(d=#l2w zNs_W=jq8AGK&xH!pb5))IX0AVdtU_(!dNa|+tF!_CD*WEr`zV5vO;gO*-JFfpZEOQhQ_B)J5b;G_cLN~qJ~W{ zVQfCGbc`&bpJ~nh;Ol|TvsB8L6}I0G$DeHTe`BqmZ1aM2yxXONbAWjG6@b!2Y9M=ic3T z(e|(f{lgSy2xToEQGKSp(Ro`XnicT+MtEonb_rDG#v#th?#DKyWu?mFj$&aLtI&qilAXJh4 zuiN!PTt~1+vr?EaHvaHWMpzVn5TuH?ea07uYZB62Yd}+|)Ga0Zxr%TizZMLs>N4s?`SRLbcj$qZ$azx?@TyaOz{m6YG+$W(m3nbt-UO` zv2FJ(#p2Mw-xImTIoFE{Olp2w;K%XE|GdN4w=U1a&$a4zcK1HK-wXMu!UNBbD7=UB%q=V}k|yh_hPdd>h}8UtEb`*lZ>e_0e{53g**(170 z;~+?qu(tCd`<5DBT$`j_h7dl?QYe__Elw+5c}LZ2UE}1VGQ32s=lD&xe6n7R_NmS8 z>b+sZKN>Na`quY=9$}cyWM-N8&}Tfj?Md%G4)lWu+7`5v%>Fj4gyGFBQLgijIrO_9 zRQeJV#Oc~>al9Ag>EL`$2cIm64vMAtlnz7|uIkg9(z|UO>0KLzg(_!b1Mg-|vi6_X zW)J;>Z?~70qJs)dNm(UepaSgj0gt3u1n3;K5og6O%JuSoExD0FdjX&q%s8)q5E z!;e>9jpt10hO}Iz491smj>PPoT{%@IRgmVLM7C^pEhMgFJ*xC@3liCzVy=Kgui=6z z6*XhwACVbnLfI=V7RMqh;;KT6<+2CA&^ZanLTljZ*(f{TVT_~S^M2A``^4Zyr7gPW zax~2LY7 z5fib}DfM!gQGex}df8B98E$Z*Sa?5?V`b^ju_-0tpT zXEQU0vilJoai-~%hXTa0wr1Q@W4zDY=6gUgKU?GY8H+Rlz*_hKH0lj5Bc=+nj0~{5 z9M|mNUGFZceZku6iutV7vcH~^zClzzC1LS!kFn*JhWW{~J;f_F1~S+nQM{YR-Ecf) zPlZv_N`5$sdcC9d!^2YkyDbWl1`YmvS9KvNr6Sdjrj{d09Y1my(;nf;*>^%BRav@y zIFf@@7`$HRfg-x675REhw%yJ+8yAGv?DD04FiJ|iaAIM?GW7mZmIuEk{i}*{sOG3?Da^m|K!^=>u_NREfN72C40WWtZhP%jCV8EHjTccLtlv6d)6!) zMC#HmKQH$f7_)?_1O}blaH0qYhCWh#D!Bjp;l3YJifDBDNrfS}O`iy_Z?n+d%m#wU zdvtb=4&36Cv}lrb*^OI=WN&x5Zu=4Hg@oZW&1y>+_kG9wz=U7K$S{2Z@i2O#Z-CG} zmic1y!AnDvN9RL9K_nZaSoL*Pgz(6_9^p?<>4;^WVohv~>pd8l&ZVFaNxo7k4~{Nv zNltt@cxk&M#l_#yX`|dSPv;`pJibX2!m<(;Be*+CYAZC+uNK>sJXS9V!2BoM{KbzI uQvcJB{VD4|{Nn%F9{wropR)e%kaZfqSV?_q|IPq@Qf~@?+SM7H@c9QQ6MxeH diff --git a/module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/test.jks b/module/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/test.jks deleted file mode 100644 index 74279d80fbac881c51e7a0fadebd9832e904240d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6536 zcmeI0c`(~++sBhg1SKS>wY8N}TkN5SB3f&Rs-^bOG?ZFmS7NK3T3aeDe?O zAP7VcpyJpH%awavkxaDo=c06?wwZvy6A%E>Rptbeo|eWGOv?%~HIZRO!hidqV`V_& zT%E7G6WyF~G6*EgZ$T(4Jr?Kc&adI>?JmQ7ywGusftA(_S{~0*JN^A0acK`f~ zhLzsc-4W;N0YU&Y z;Xq~pG91VN3I_rK^%hFNu#-#uchOu0C81Yb1T$PF^G9e`u9?bJUu$OJQlq5tPF`o{ zC3MUU2pEf8zgeJuRSUD9YS`S)+l=JqiT0y?MvJPeTH!L9x9PNINX*lr6)fObjirmd zd20m0)h4Qz*qk{G=v32|qDC&WOEAyiaRA;`y6=M~8k3eqA7)Or`i(wOJzbF}=bgRI zSou~_x|~%4tmb~b?MY3tZSY9NMb%(tRMQYE?kk5?vW<2$j~?2>GqVDJCf+{Bu3AvA z=3V?q32>@J$gZc%y73(BD^q|rBX?(;j2_V~hd7hrHM^@0KOGoHpWLBoEQt8({;~@j z4UA8Gg$@@<0?_~gz&s-)26^guw@<;qC&6rH87)h$y*5_LS%c_Xn}OJSYu1mE62DEu z!NN$P@ISXZn&r4%|2lxt;E>~9{cFjOd+@mAKmdcblT_+MejJ`A$v0+V|&vU(Knyb-_UPUUok+VWdi<6$iGN~_!v|7168uQZBsX`dnWFp zDj6`y6FoFx6I>ToAswf;V_Y~?Nq6bB3`_6XfGjljNyaHeIK8`YGhG83nLX}{Hb2Yd zz#djXZKPex6<#SGMt^6f?v4>hF`wzw^Y+-Gk*|jex{Y$m*)Qh1_5JF#AbIPF+*luV zF>x~Ol6MD>RPur6^;*ajzgCec+%b+ayO<2mYN-0sv-6DHI`;0dT!{+@CeSiZVZ`7( zGP5=W52Sw`!}$5L%#=z}woIm>NHA0>)2rF{Z?`YYSPsvr6k4f4fQCT&8K-G#$sG3%A< zxpZ^Yx|?;wAs(V;g8f$U@@KBSnH6bmF_*Tu?6=#l^O?Z1?15TkytxuZeyi2nY8n5w zcK|K*kU!CUj)PZ-&~XhnPuS!sJqsSkExz4~5pcG3W9p`12!IH88KK5M7R zF_|OSdqiqM&A+{6K5$-t6?x?KAsQR)$WXZ$IcvxJnW&0=#9A;N*A(#wf z`aCKNX^n1;2%8WdTH{SiQ2+d`6kINwK<`kjAAPX6EukBSw;q@`iH1A*49{4ZY@UB{ znLS`>`G>$>K@Hl3)G5#cU7U=mHLPl#8`L}3A#g{rb}%?4p&aujNXtvt^F_5Y=i+T2 zRg&wtg_!|amO4}fi+Ad(@n&#Jw*R(FDP3z;(%iBaV3r8uW;`ObW;^+E3w{<_fK8;f za9AoE&u~~a&MRm=y(zM4%5pf-T+yr7@Bs1pMuC*xOp)k1HaR2lG)+5|tG6@&ubI0= z=IDHHS5kuIyAXfv&`y%C*dKQfNtCBOD|@fvJI%tAJ-kD0i=PIp=jLWi=Ld@QRFmXQ zd=k*Dhc!B=n>}o^gEi(deUV*Jr=}8h{LEb?%BYxAl$%u58C6dyover7MTgJugn4qO zreCn}PMMxNm6vG<$a=lgAqG#%=Xow)46?7qZ(6-rkTYl}+{XOf* zPMOGrjG6*Pu*yC$H%)x7+6E?8*#8RQMT+rBn&UCAT;wqW0HJCbZhGS%zuKnr3bZiL zo-fq&0&P?0-h6ne{7i(R)4J`{E)xn24~JjyKXA(T$nA$&VaaM`J>;y!qL-OZHL~V} zI`h-c5Tjxr_+%?Gan{@u?Xtoq)n(GJE$9Wm+_s79qJO7x>t^iPV)q&v^GU7d6rFX< z0>-Jf?Xt@QZtZ=FjA_{^g1X_F*uJs+hbrVZ=j99O0!w<_UecBBZ|X0;3eWYhq8S>3 z^BHZQLkf6Mo*;$-qY4Cx%Hu8w2r;6aK|7^J4n1UZ0)g4T$I@<+v~?f;ia$%WE4gc1 z;xeN)U-a8}S;>y0p`eO^Mv{Dcs%diRw;Rv5`za|?yQ!ZW@iH!$Y{w3}AvE(d=#l2w zNs_W=jq8AGK&xH!pb5))IX0AVdtU_(!dNa|+tF!_CD*WEr`zV5vO;gO*-JFfpZEOQhQ_B)J5b;G_cLN~qJ~W{ zVQfCGbc`&bpJ~nh;Ol|TvsB8L6}I0G$DeHTe`BqmZ1aM2yxXONbAWjG6@b!2Y9M=ic3T z(e|(f{lgSy2xToEQGKSp(Ro`XnicT+MtEonb_rDG#v#th?#DKyWu?mFj$&aLtI&qilAXJh4 zuiN!PTt~1+vr?EaHvaHWMpzVn5TuH?ea07uYZB62Yd}+|)Ga0Zxr%TizZMLs>N4s?`SRLbcj$qZ$azx?@TyaOz{m6YG+$W(m3nbt-UO` zv2FJ(#p2Mw-xImTIoFE{Olp2w;K%XE|GdN4w=U1a&$a4zcK1HK-wXMu!UNBbD7=UB%q=V}k|yh_hPdd>h}8UtEb`*lZ>e_0e{53g**(170 z;~+?qu(tCd`<5DBT$`j_h7dl?QYe__Elw+5c}LZ2UE}1VGQ32s=lD&xe6n7R_NmS8 z>b+sZKN>Na`quY=9$}cyWM-N8&}Tfj?Md%G4)lWu+7`5v%>Fj4gyGFBQLgijIrO_9 zRQeJV#Oc~>al9Ag>EL`$2cIm64vMAtlnz7|uIkg9(z|UO>0KLzg(_!b1Mg-|vi6_X zW)J;>Z?~70qJs)dNm(UepaSgj0gt3u1n3;K5og6O%JuSoExD0FdjX&q%s8)q5E z!;e>9jpt10hO}Iz491smj>PPoT{%@IRgmVLM7C^pEhMgFJ*xC@3liCzVy=Kgui=6z z6*XhwACVbnLfI=V7RMqh;;KT6<+2CA&^ZanLTljZ*(f{TVT_~S^M2A``^4Zyr7gPW zax~2LY7 z5fib}DfM!gQGex}df8B98E$Z*Sa?5?V`b^ju_-0tpT zXEQU0vilJoai-~%hXTa0wr1Q@W4zDY=6gUgKU?GY8H+Rlz*_hKH0lj5Bc=+nj0~{5 z9M|mNUGFZceZku6iutV7vcH~^zClzzC1LS!kFn*JhWW{~J;f_F1~S+nQM{YR-Ecf) zPlZv_N`5$sdcC9d!^2YkyDbWl1`YmvS9KvNr6Sdjrj{d09Y1my(;nf;*>^%BRav@y zIFf@@7`$HRfg-x675REhw%yJ+8yAGv?DD04FiJ|iaAIM?GW7mZmIuEk{i}*{sOG3?Da^m|K!^=>u_NREfN72C40WWtZhP%jCV8EHjTccLtlv6d)6!) zMC#HmKQH$f7_)?_1O}blaH0qYhCWh#D!Bjp;l3YJifDBDNrfS}O`iy_Z?n+d%m#wU zdvtb=4&36Cv}lrb*^OI=WN&x5Zu=4Hg@oZW&1y>+_kG9wz=U7K$S{2Z@i2O#Z-CG} zmic1y!AnDvN9RL9K_nZaSoL*Pgz(6_9^p?<>4;^WVohv~>pd8l&ZVFaNxo7k4~{Nv zNltt@cxk&M#l_#yX`|dSPv;`pJibX2!m<(;Be*+CYAZC+uNK>sJXS9V!2BoM{KbzI uQvcJB{VD4|{Nn%F9{wropR)e%kaZfqSV?_q|IPq@Qf~@?+SM7H@c9QQ6MxeH diff --git a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java index 8efb6d2634b..ff6a636ce8b 100644 --- a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java +++ b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java @@ -616,8 +616,8 @@ public abstract class AbstractReactiveWebServerFactoryTests { ConfigurableReactiveWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); - assertThat(startedLogMessage()).matches( - "(Jetty|Netty|Tomcat|Undertow) started on port " + this.webServer.getPort() + " \\(http(/1.1)?\\)"); + assertThat(startedLogMessage()) + .matches("(Jetty|Netty|Tomcat) started on port " + this.webServer.getPort() + " \\(http(/1.1)?\\)"); } @Test @@ -626,7 +626,7 @@ public abstract class AbstractReactiveWebServerFactoryTests { addConnector(0, factory); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); - assertThat(startedLogMessage()).matches("(Jetty|Tomcat|Undertow) started on ports " + this.webServer.getPort() + assertThat(startedLogMessage()).matches("(Jetty|Tomcat) started on ports " + this.webServer.getPort() + " \\(http(/1.1)?\\), [0-9]+ \\(http(/1.1)?\\)"); } diff --git a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java index 3b98f7cd7a6..fc0c98b6448 100644 --- a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java +++ b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java @@ -1372,7 +1372,7 @@ public abstract class AbstractServletWebServerFactoryTests { ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); this.webServer.start(); - assertThat(startedLogMessage()).matches("(Jetty|Tomcat|Undertow) started on port " + this.webServer.getPort() + assertThat(startedLogMessage()).matches("(Jetty|Tomcat) started on port " + this.webServer.getPort() + " \\(http(/1.1)?\\) with context path '/'"); } @@ -1382,7 +1382,7 @@ public abstract class AbstractServletWebServerFactoryTests { factory.setContextPath("/test"); this.webServer = factory.getWebServer(); this.webServer.start(); - assertThat(startedLogMessage()).matches("(Jetty|Tomcat|Undertow) started on port " + this.webServer.getPort() + assertThat(startedLogMessage()).matches("(Jetty|Tomcat) started on port " + this.webServer.getPort() + " \\(http(/1.1)?\\) with context path '/test'"); } @@ -1392,7 +1392,7 @@ public abstract class AbstractServletWebServerFactoryTests { addConnector(0, factory); this.webServer = factory.getWebServer(); this.webServer.start(); - assertThat(startedLogMessage()).matches("(Jetty|Tomcat|Undertow) started on ports " + this.webServer.getPort() + assertThat(startedLogMessage()).matches("(Jetty|Tomcat) started on ports " + this.webServer.getPort() + " \\(http(/1.1)?\\), [0-9]+ \\(http(/1.1)?\\) with context path '/'"); } diff --git a/module/spring-boot-webmvc/build.gradle b/module/spring-boot-webmvc/build.gradle index 5963ab37d89..d78b5a79050 100644 --- a/module/spring-boot-webmvc/build.gradle +++ b/module/spring-boot-webmvc/build.gradle @@ -40,7 +40,6 @@ dependencies { optional(project(":module:spring-boot-metrics")) optional(project(":module:spring-boot-observation")) optional(project(":module:spring-boot-tomcat")) - optional(project(":module:spring-boot-undertow")) optional(project(":module:spring-boot-validation")) optional(project(":module:spring-boot-web-server")) optional("com.fasterxml.jackson.core:jackson-databind") diff --git a/module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java b/module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java index 75b4cec5280..893b5f308ff 100644 --- a/module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java +++ b/module/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java @@ -21,14 +21,12 @@ import java.util.List; import java.util.Optional; import java.util.stream.Stream; -import io.undertow.servlet.api.DeploymentManager; import jakarta.servlet.ServletException; import org.apache.catalina.Container; import org.apache.catalina.Context; import org.apache.catalina.core.StandardWrapper; import org.springframework.boot.tomcat.TomcatWebServer; -import org.springframework.boot.undertow.servlet.UndertowServletWebServer; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; import org.springframework.util.ClassUtils; @@ -48,10 +46,6 @@ final class DispatcherServletHandlerMappings { private static final boolean TOMCAT_WEB_SERVER_PRESENT = ClassUtils.isPresent( "org.springframework.boot.tomcat.TomcatWebServer", DispatcherServletHandlerMappings.class.getClassLoader()); - private static final boolean UNDERTOW_WEB_SERVER_PRESENT = ClassUtils.isPresent( - "org.springframework.boot.undertow.UndertowWebServer", - DispatcherServletHandlerMappings.class.getClassLoader()); - private final String name; private final DispatcherServlet dispatcherServlet; @@ -79,10 +73,7 @@ final class DispatcherServletHandlerMappings { return; } WebServer webServer = webServerApplicationContext.getWebServer(); - if (UNDERTOW_WEB_SERVER_PRESENT && webServer instanceof UndertowServletWebServer undertowServletWebServer) { - new UndertowServletInitializer(undertowServletWebServer).initializeServlet(this.name); - } - else if (TOMCAT_WEB_SERVER_PRESENT && webServer instanceof TomcatWebServer tomcatWebServer) { + if (TOMCAT_WEB_SERVER_PRESENT && webServer instanceof TomcatWebServer tomcatWebServer) { new TomcatServletInitializer(tomcatWebServer).initializeServlet(this.name); } } @@ -124,26 +115,4 @@ final class DispatcherServletHandlerMappings { } - private static final class UndertowServletInitializer { - - private final UndertowServletWebServer webServer; - - private UndertowServletInitializer(UndertowServletWebServer webServer) { - this.webServer = webServer; - } - - void initializeServlet(String name) { - try { - DeploymentManager deploymentManager = this.webServer.getDeploymentManager(); - if (deploymentManager != null) { - deploymentManager.getDeployment().getServlets().getManagedServlet(name).forceInit(); - } - } - catch (ServletException ex) { - // Continue - } - } - - } - } diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index b1407e3bbe1..c3c546e2308 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2153,7 +2153,6 @@ bom { "spring-boot-starter-test", "spring-boot-starter-thymeleaf", "spring-boot-starter-tomcat", - "spring-boot-starter-undertow", "spring-boot-starter-validation", "spring-boot-starter-web", "spring-boot-starter-web-services", @@ -2170,7 +2169,6 @@ bom { "spring-boot-tomcat", "spring-boot-tracing", "spring-boot-tx", - "spring-boot-undertow", "spring-boot-validation", "spring-boot-webclient", "spring-boot-webflux", @@ -2652,18 +2650,6 @@ bom { releaseNotes("https://github.com/pingidentity/ldapsdk/releases/tag/{version}") } } - library("Undertow", "2.3.18.Final") { - group("io.undertow") { - modules = [ - "undertow-core", - "undertow-servlet", - "undertow-websockets-jsr" - ] - } - links { - releaseNotes("https://github.com/undertow-io/undertow/releases/tag/{version}") - } - } library("Versions Maven Plugin", "2.18.0") { group("org.codehaus.mojo") { plugins = [ diff --git a/settings.gradle b/settings.gradle index 4f2cfa7992c..391da6eb254 100644 --- a/settings.gradle +++ b/settings.gradle @@ -160,7 +160,6 @@ include "module:spring-boot-thymeleaf" include "module:spring-boot-tomcat" include "module:spring-boot-tracing" include "module:spring-boot-tx" -include "module:spring-boot-undertow" include "module:spring-boot-validation" include "module:spring-boot-web-server" // FIXME move to core? include "module:spring-boot-web-server-test" // FIXME move to core? @@ -252,7 +251,6 @@ include "starter:spring-boot-starter-sql" include "starter:spring-boot-starter-test" include "starter:spring-boot-starter-thymeleaf" include "starter:spring-boot-starter-tomcat" -include "starter:spring-boot-starter-undertow" include "starter:spring-boot-starter-validation" include "starter:spring-boot-starter-web" include "starter:spring-boot-starter-web-services" @@ -355,8 +353,6 @@ include ":smoke-test:spring-boot-smoke-test-tomcat-jsp" include ":smoke-test:spring-boot-smoke-test-tomcat-multi-connectors" include ":smoke-test:spring-boot-smoke-test-tomcat-ssl" include ":smoke-test:spring-boot-smoke-test-traditional" -include ":smoke-test:spring-boot-smoke-test-undertow" -include ":smoke-test:spring-boot-smoke-test-undertow-ssl" include ":smoke-test:spring-boot-smoke-test-war" include ":smoke-test:spring-boot-smoke-test-web-application-type" include ":smoke-test:spring-boot-smoke-test-web-freemarker" @@ -374,7 +370,6 @@ include ":smoke-test:spring-boot-smoke-test-webflux-coroutines" include ":smoke-test:spring-boot-smoke-test-webservices" include ":smoke-test:spring-boot-smoke-test-websocket-jetty" include ":smoke-test:spring-boot-smoke-test-websocket-tomcat" -include ":smoke-test:spring-boot-smoke-test-websocket-undertow" include ":smoke-test:spring-boot-smoke-test-xml" include ":integration-test:spring-boot-actuator-integration-tests" diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/build.gradle b/smoke-test/spring-boot-smoke-test-undertow-ssl/build.gradle deleted file mode 100644 index 9e0e40d015e..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "java" -} - -description = "Spring Boot Undertow SSL smoke test" - -dependencies { - implementation(project(":starter:spring-boot-starter-webmvc")) { - exclude module: "spring-boot-starter-tomcat" - } - implementation(project(":starter:spring-boot-starter-undertow")) - - testImplementation(project(":starter:spring-boot-starter-restclient")) - testImplementation(project(":starter:spring-boot-starter-test")) - testImplementation("org.apache.httpcomponents.client5:httpclient5") -} diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/SampleUndertowSslApplication.java b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/SampleUndertowSslApplication.java deleted file mode 100644 index acc60ac640a..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/SampleUndertowSslApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow.ssl; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SampleUndertowSslApplication { - - public static void main(String[] args) { - SpringApplication.run(SampleUndertowSslApplication.class, args); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/package-info.java b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/package-info.java deleted file mode 100644 index d21ba4e64f8..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.undertow.ssl; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/SampleController.java b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/SampleController.java deleted file mode 100644 index 52bcc7dcaa3..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/SampleController.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow.ssl.web; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class SampleController { - - @GetMapping("/") - public String helloWorld() { - return "Hello World"; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/package-info.java b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/package-info.java deleted file mode 100644 index 12d5e4d0a4b..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/java/smoketest/undertow/ssl/web/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.undertow.ssl.web; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/application.properties b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/application.properties deleted file mode 100644 index 37199bfd256..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -server.port = 8443 -server.ssl.key-store = classpath:sample.jks -server.ssl.key-store-password = secret -server.ssl.key-password = password diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/sample.jks b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/main/resources/sample.jks deleted file mode 100644 index 6aa9a28053a591e41453e665e5024e8a8cb78b3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2264 zcmchYX*3iJ7sqE|hQS!q5Mv)4GM2$i#uAFqC`%7x7baWA*i&dRX>3`uq(XS?3XSYp z%38`&ib7E$8j~$cF^}gt?|I+noW8#w?uYxk=iGD8|K9Vzd#pVc0002(2k@T|2@MMI zqxqr2AhQO*TVi`j@((S;e;g;l$#dAA{>vf0kX$R(Qn4oKgGEYjZ5zti2dw?Z6A zh%LuFCNI?9o+Z1duJL-++e#cjO`zlK?u9s030=k_*wD1#-$FbIDRDnA^vo@fm( zzjt(3VJrGOr0iHXSTM|rYN#>RZ@Dp`PwB2zrDQffLvuoR2~V3ReYa0&vU^dXd8isV zsAf*@!8s%xBvHLseXn6f?1kefe(8uAmAbaF$x{Ykzb6c6jdUwY1$y4tFzsj7 zIghr!T#ODfu@Po!a29@kXQ8kY#(LE<0o7?7PQ|eMeY@Equ?R-6*f@Na3o&stDQ=6( zQzDSQhCnS(9Bu9W_~giknP0vECqUsr4_9y_}nEU`cy z4}dApnAip92wMwgzciAFpc3i}+-#Zlq+iF7d1y}d4Qsp8=%l1N8NIs161I`HmkcpQ zY4*CUCFJJf(2!M{`&qQ}3($KeTQ=)mMrBs`DOb;%Of0tC)9he_p~w&CO#DfCgx(%s z{@|D(brX_Gb}ZDLmGej*JgEl0Et>q~kgTXuJg-PwvRjNx8sBbIShxD=xOySzw{;^X zAvrh5HTg>Xq@<{#^!Kg}B?qz@b<{ebD)yaSf&RChBIJQo-?Ahzw@qopSe^e&>^IuU zydM4Y1_C&>k7u|}=; z63R7$H6zat=hNExxEwXu1fQ*ytuEkP!{w{|#6TIEq1#*ck=6_NM*ILF65tmD-O5&R zMI!-MT<3U~t@}(CN4@RlZ~1I>C=!ywF)dNI{VvH;5Y3(Z4jY^%_c&fsm4Q`<1g|qX z&!h29jXjVE3nJnet*L)XL?-8<>qDbVGP%i^NwOZfwWO7?Mr!X7 zl}sG@9S_5}}td}$xrWIYY=e(VVBiv%A+M-{M z!3_^Tc=pV?niT!{D`!{e@W;MvrZ(OER{x7itVAtwE~spPtPtma|J=5dv&_oE!5H#` zdgXJ;+gJ4hI}*9QX9jpL`Gb)yCe%1}t!&O-^sihyZys%%5uF~WhsR_w(q7;vV5d4P zr%ZUA2}kO+L^2ePTgGT9Ua71w<+)poSyjTdLq&xbUn`<6&SpwFp(HRHUyU6J3WZ_! zfztko79+94Tq%mTYj53(RYcL&1~5`I#+w3`(Q|r+P(aT z%?r(^?IWw~19CB&uvXf(f7&BnEE{zwK4piVU`I4j1j?v5d4N<7VUJ8nM`$7S*mfKR z#9-JzPRZ?{M!@L+0N^V)IyeeP2T|^UK|m0QD+Ibs!wEoml^N!YO#vW~j~jraX(0A3 z6Kux?IRLez`O^X;{!4g%BhcRn>^H*qKZ3*|{_YGuz)KCJcu;)DSES5D2tDE`C02YR0R%Vy1T7k|RQ;3g<0icA$AuP0pOvc~jGl zz+NeKv_FT_;GWK&8XlDUv&hv9kxg?@c!bu?83i=YQ$S!K09Y)Glg3Hz?@|)ZCBlVz zP8i}#XZkMoje3I=h&I!!s_m?Qi@1MR`yv7X*yEs47qOs^t^?&=;*IQ!q&)gq_Sx5* z?fhU8Q*PSe*w7y)FH#P!9R^Xw!lTT+zI39L<&8cViaj$A(Z2Cg7!{V?uuyi#vlNCg z40i}2ivw&y&1-&Nh&WMG`&aIt>)(#tKTJ}^@696Kw1-{IzSOTnFF+0@k$o3%ZHS;Q#;t diff --git a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java b/smoke-test/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java deleted file mode 100644 index 88b9e88c310..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow.ssl; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.boot.web.server.test.client.TestRestTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Basic integration tests for demo application. - * - * @author Ivan Sopov - */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class SampleUndertowSslApplicationTests { - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private AbstractConfigurableWebServerFactory webServerFactory; - - @Test - void testSsl() { - assertThat(this.webServerFactory.getSsl().isEnabled()).isTrue(); - } - - @Test - void testHome() { - ResponseEntity entity = this.restTemplate.getForEntity("/", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).isEqualTo("Hello World"); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-undertow/build.gradle b/smoke-test/spring-boot-smoke-test-undertow/build.gradle deleted file mode 100644 index 944f37a2215..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "java" -} - -description = "Spring Boot Undertow smoke test" - -dependencies { - implementation(project(":starter:spring-boot-starter-webmvc")) { - exclude module: "spring-boot-starter-tomcat" - } - implementation(project(":starter:spring-boot-starter-undertow")) - - testImplementation(project(":starter:spring-boot-starter-restclient")) - testImplementation(project(":starter:spring-boot-starter-test")) -} diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/SampleUndertowApplication.java b/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/SampleUndertowApplication.java deleted file mode 100644 index 85e0287d933..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/SampleUndertowApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SampleUndertowApplication { - - public static void main(String[] args) { - SpringApplication.run(SampleUndertowApplication.class, args); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/package-info.java b/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/package-info.java deleted file mode 100644 index 79c9783ded7..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.undertow; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/SampleController.java b/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/SampleController.java deleted file mode 100644 index 189d914500f..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/SampleController.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow.web; - -import java.util.concurrent.Callable; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class SampleController { - - @GetMapping("/") - public String helloWorld() { - return "Hello World"; - } - - @GetMapping("/async") - public Callable helloWorldAsync() { - return () -> "async: Hello World"; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/package-info.java b/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/package-info.java deleted file mode 100644 index df2d526c9cc..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/main/java/smoketest/undertow/web/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.undertow.web; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/main/resources/application.properties b/smoke-test/spring-boot-smoke-test-undertow/src/main/resources/application.properties deleted file mode 100644 index 7dfb55689a3..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -server.undertow.accesslog.enabled=true -server.undertow.accesslog.dir=target/logs -server.undertow.accesslog.pattern=combined -server.compression.enabled=true -server.compression.min-response-size=1 diff --git a/smoke-test/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java b/smoke-test/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java deleted file mode 100644 index d574ad36b7a..00000000000 --- a/smoke-test/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.undertow; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; -import java.util.zip.GZIPInputStream; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Basic integration tests for demo application. - * - * @author Ivan Sopov - * @author Andy Wilkinson - */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class SampleUndertowApplicationTests { - - @Autowired - private TestRestTemplate restTemplate; - - @Test - void testHome() { - assertOkResponse("/", "Hello World"); - } - - @Test - void testAsync() { - assertOkResponse("/async", "async: Hello World"); - } - - @Test - void testCompression() throws Exception { - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.set("Accept-Encoding", "gzip"); - HttpEntity requestEntity = new HttpEntity<>(requestHeaders); - ResponseEntity entity = this.restTemplate.exchange("/", HttpMethod.GET, requestEntity, byte[].class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - - try (GZIPInputStream inflater = new GZIPInputStream(new ByteArrayInputStream(entity.getBody()))) { - assertThat(StreamUtils.copyToString(inflater, StandardCharsets.UTF_8)).isEqualTo("Hello World"); - } - } - - private void assertOkResponse(String path, String body) { - ResponseEntity entity = this.restTemplate.getForEntity(path, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).isEqualTo(body); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/build.gradle b/smoke-test/spring-boot-smoke-test-websocket-undertow/build.gradle deleted file mode 100644 index f2fd1d0ece8..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "java" -} - -description = "Spring Boot WebSocket Undertow smoke test" - -dependencies { - implementation(project(":starter:spring-boot-starter-undertow")) - implementation(project(":starter:spring-boot-starter-websocket")) { - exclude module: "spring-boot-starter-tomcat" - } - - testImplementation(project(":starter:spring-boot-starter-test")) -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/SampleUndertowWebSocketsApplication.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/SampleUndertowWebSocketsApplication.java deleted file mode 100644 index caf1b7909ba..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/SampleUndertowWebSocketsApplication.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow; - -import smoketest.websocket.undertow.client.GreetingService; -import smoketest.websocket.undertow.client.SimpleGreetingService; -import smoketest.websocket.undertow.echo.DefaultEchoService; -import smoketest.websocket.undertow.echo.EchoService; -import smoketest.websocket.undertow.echo.EchoWebSocketHandler; -import smoketest.websocket.undertow.reverse.ReverseWebSocketEndpoint; -import smoketest.websocket.undertow.snake.SnakeWebSocketHandler; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.config.annotation.EnableWebSocket; -import org.springframework.web.socket.config.annotation.WebSocketConfigurer; -import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; -import org.springframework.web.socket.handler.PerConnectionWebSocketHandler; -import org.springframework.web.socket.server.standard.ServerEndpointExporter; - -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@EnableWebSocket -public class SampleUndertowWebSocketsApplication extends SpringBootServletInitializer implements WebSocketConfigurer { - - @Override - public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { - registry.addHandler(echoWebSocketHandler(), "/echo").setAllowedOrigins("*").withSockJS(); - registry.addHandler(snakeWebSocketHandler(), "/snake").setAllowedOrigins("*").withSockJS(); - } - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(SampleUndertowWebSocketsApplication.class); - } - - @Bean - public EchoService echoService() { - return new DefaultEchoService("Did you say \"%s\"?"); - } - - @Bean - public GreetingService greetingService() { - return new SimpleGreetingService(); - } - - @Bean - public WebSocketHandler echoWebSocketHandler() { - return new EchoWebSocketHandler(echoService()); - } - - @Bean - public WebSocketHandler snakeWebSocketHandler() { - return new PerConnectionWebSocketHandler(SnakeWebSocketHandler.class); - } - - @Bean - public ReverseWebSocketEndpoint reverseWebSocketEndpoint() { - return new ReverseWebSocketEndpoint(); - } - - @Bean - public ServerEndpointExporter serverEndpointExporter() { - return new ServerEndpointExporter(); - } - - public static void main(String[] args) { - SpringApplication.run(SampleUndertowWebSocketsApplication.class, args); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/GreetingService.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/GreetingService.java deleted file mode 100644 index c577a4067ff..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/GreetingService.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.client; - -public interface GreetingService { - - String getGreeting(); - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleClientWebSocketHandler.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleClientWebSocketHandler.java deleted file mode 100644 index fdc596d350c..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleClientWebSocketHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.client; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.handler.TextWebSocketHandler; - -public class SimpleClientWebSocketHandler extends TextWebSocketHandler { - - protected Log logger = LogFactory.getLog(SimpleClientWebSocketHandler.class); - - private final GreetingService greetingService; - - private final CountDownLatch latch; - - private final AtomicReference messagePayload; - - public SimpleClientWebSocketHandler(GreetingService greetingService, CountDownLatch latch, - AtomicReference message) { - this.greetingService = greetingService; - this.latch = latch; - this.messagePayload = message; - } - - @Override - public void afterConnectionEstablished(WebSocketSession session) throws Exception { - TextMessage message = new TextMessage(this.greetingService.getGreeting()); - session.sendMessage(message); - } - - @Override - public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { - this.logger.info("Received: " + message + " (" + this.latch.getCount() + ")"); - session.close(); - this.messagePayload.set(message.getPayload()); - this.latch.countDown(); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleGreetingService.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleGreetingService.java deleted file mode 100644 index ae49a49704f..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/SimpleGreetingService.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.client; - -public class SimpleGreetingService implements GreetingService { - - @Override - public String getGreeting() { - return "Hello world!"; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/package-info.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/package-info.java deleted file mode 100644 index c85883b6f99..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.websocket.undertow.client; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/DefaultEchoService.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/DefaultEchoService.java deleted file mode 100644 index c0878b6168b..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/DefaultEchoService.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.echo; - -import org.jspecify.annotations.Nullable; - -public class DefaultEchoService implements EchoService { - - private final String echoFormat; - - public DefaultEchoService(@Nullable String echoFormat) { - this.echoFormat = (echoFormat != null) ? echoFormat : "%s"; - } - - @Override - public String getMessage(String message) { - return String.format(this.echoFormat, message); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoService.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoService.java deleted file mode 100644 index fabc287cc3f..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoService.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.echo; - -public interface EchoService { - - String getMessage(String message); - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoWebSocketHandler.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoWebSocketHandler.java deleted file mode 100644 index 8eb6d19bbcc..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/EchoWebSocketHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.echo; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.web.socket.CloseStatus; -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.handler.TextWebSocketHandler; - -/** - * Echo messages by implementing a Spring {@link WebSocketHandler} abstraction. - */ -public class EchoWebSocketHandler extends TextWebSocketHandler { - - private static final Log logger = LogFactory.getLog(EchoWebSocketHandler.class); - - private final EchoService echoService; - - public EchoWebSocketHandler(EchoService echoService) { - this.echoService = echoService; - } - - @Override - public void afterConnectionEstablished(WebSocketSession session) { - logger.debug("Opened new session in instance " + this); - } - - @Override - public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { - String echoMessage = this.echoService.getMessage(message.getPayload()); - logger.debug(echoMessage); - session.sendMessage(new TextMessage(echoMessage)); - } - - @Override - public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { - session.close(CloseStatus.SERVER_ERROR); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/package-info.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/package-info.java deleted file mode 100644 index 1406b42e9df..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/echo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.websocket.undertow.echo; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/package-info.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/package-info.java deleted file mode 100644 index b8a8785b402..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.websocket.undertow; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/ReverseWebSocketEndpoint.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/ReverseWebSocketEndpoint.java deleted file mode 100644 index fe57c51c51d..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/ReverseWebSocketEndpoint.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.reverse; - -import java.io.IOException; - -import jakarta.websocket.OnMessage; -import jakarta.websocket.Session; -import jakarta.websocket.server.ServerEndpoint; - -@ServerEndpoint("/reverse") -public class ReverseWebSocketEndpoint { - - @OnMessage - public void handleMessage(Session session, String message) throws IOException { - session.getBasicRemote().sendText("Reversed: " + new StringBuilder(message).reverse()); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/package-info.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/package-info.java deleted file mode 100644 index c336f4e3026..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/reverse/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.websocket.undertow.reverse; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Direction.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Direction.java deleted file mode 100644 index f739ed31536..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Direction.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -public enum Direction { - - NONE, NORTH, SOUTH, EAST, WEST - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Location.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Location.java deleted file mode 100644 index c86aae589fb..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Location.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import org.jspecify.annotations.Nullable; - -public class Location { - - /** - * The X location. - */ - public int x; - - /** - * The Y location. - */ - public int y; - - public Location(int x, int y) { - this.x = x; - this.y = y; - } - - public Location getAdjacentLocation(Direction direction) { - return switch (direction) { - case NORTH -> new Location(this.x, this.y - SnakeUtils.GRID_SIZE); - case SOUTH -> new Location(this.x, this.y + SnakeUtils.GRID_SIZE); - case EAST -> new Location(this.x + SnakeUtils.GRID_SIZE, this.y); - case WEST -> new Location(this.x - SnakeUtils.GRID_SIZE, this.y); - case NONE -> this; - }; - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Location location = (Location) o; - if (this.x != location.x) { - return false; - } - return this.y == location.y; - } - - @Override - public int hashCode() { - int result = this.x; - result = 31 * result + this.y; - return result; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Snake.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Snake.java deleted file mode 100644 index 215a279471b..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/Snake.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Deque; - -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketSession; - -public class Snake { - - private static final int DEFAULT_LENGTH = 5; - - private final Deque tail = new ArrayDeque<>(); - - private final Object monitor = new Object(); - - private final int id; - - private final WebSocketSession session; - - private final String hexColor; - - private Direction direction; - - private int length = DEFAULT_LENGTH; - - private Location head; - - public Snake(int id, WebSocketSession session) { - this.id = id; - this.session = session; - this.hexColor = SnakeUtils.getRandomHexColor(); - resetState(); - } - - private void resetState() { - this.direction = Direction.NONE; - this.head = SnakeUtils.getRandomLocation(); - this.tail.clear(); - this.length = DEFAULT_LENGTH; - } - - private void kill() throws Exception { - synchronized (this.monitor) { - resetState(); - sendMessage("{'type': 'dead'}"); - } - } - - private void reward() throws Exception { - synchronized (this.monitor) { - this.length++; - sendMessage("{'type': 'kill'}"); - } - } - - protected void sendMessage(String msg) throws Exception { - this.session.sendMessage(new TextMessage(msg)); - } - - public void update(Collection snakes) throws Exception { - synchronized (this.monitor) { - Location nextLocation = this.head.getAdjacentLocation(this.direction); - if (nextLocation.x >= SnakeUtils.PLAYFIELD_WIDTH) { - nextLocation.x = 0; - } - if (nextLocation.y >= SnakeUtils.PLAYFIELD_HEIGHT) { - nextLocation.y = 0; - } - if (nextLocation.x < 0) { - nextLocation.x = SnakeUtils.PLAYFIELD_WIDTH; - } - if (nextLocation.y < 0) { - nextLocation.y = SnakeUtils.PLAYFIELD_HEIGHT; - } - if (this.direction != Direction.NONE) { - this.tail.addFirst(this.head); - if (this.tail.size() > this.length) { - this.tail.removeLast(); - } - this.head = nextLocation; - } - - handleCollisions(snakes); - } - } - - private void handleCollisions(Collection snakes) throws Exception { - for (Snake snake : snakes) { - boolean headCollision = this.id != snake.id && snake.getHead().equals(this.head); - boolean tailCollision = snake.getTail().contains(this.head); - if (headCollision || tailCollision) { - kill(); - if (this.id != snake.id) { - snake.reward(); - } - } - } - } - - public Location getHead() { - synchronized (this.monitor) { - return this.head; - } - } - - public Collection getTail() { - synchronized (this.monitor) { - return this.tail; - } - } - - public void setDirection(Direction direction) { - synchronized (this.monitor) { - this.direction = direction; - } - } - - public String getLocationsJson() { - synchronized (this.monitor) { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("{x: %d, y: %d}", this.head.x, this.head.y)); - for (Location location : this.tail) { - sb.append(','); - sb.append(String.format("{x: %d, y: %d}", location.x, location.y)); - } - return String.format("{'id':%d,'body':[%s]}", this.id, sb); - } - } - - public int getId() { - return this.id; - } - - public String getHexColor() { - return this.hexColor; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeTimer.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeTimer.java deleted file mode 100644 index dc712240989..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeTimer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -import jakarta.annotation.Nullable; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Sets up the timer for the multiplayer snake game WebSocket example. - */ -public final class SnakeTimer { - - private static final long TICK_DELAY = 100; - - private static final Object MONITOR = new Object(); - - private static final Log logger = LogFactory.getLog(SnakeTimer.class); - - private static final ConcurrentHashMap snakes = new ConcurrentHashMap<>(); - - private static @Nullable Timer gameTimer; - - private SnakeTimer() { - } - - public static void addSnake(Snake snake) { - synchronized (MONITOR) { - if (snakes.isEmpty()) { - startTimer(); - } - snakes.put(snake.getId(), snake); - } - } - - public static Collection getSnakes() { - return Collections.unmodifiableCollection(snakes.values()); - } - - public static void removeSnake(Snake snake) { - synchronized (MONITOR) { - snakes.remove(snake.getId()); - if (snakes.isEmpty()) { - stopTimer(); - } - } - } - - public static void tick() throws Exception { - StringBuilder sb = new StringBuilder(); - for (Iterator iterator = SnakeTimer.getSnakes().iterator(); iterator.hasNext();) { - Snake snake = iterator.next(); - snake.update(SnakeTimer.getSnakes()); - sb.append(snake.getLocationsJson()); - if (iterator.hasNext()) { - sb.append(','); - } - } - broadcast(String.format("{'type': 'update', 'data' : [%s]}", sb)); - } - - public static void broadcast(String message) { - Collection snakes = new CopyOnWriteArrayList<>(SnakeTimer.getSnakes()); - for (Snake snake : snakes) { - try { - snake.sendMessage(message); - } - catch (Throwable ex) { - // if Snake#sendMessage fails the client is removed - removeSnake(snake); - } - } - } - - public static void startTimer() { - gameTimer = new Timer(SnakeTimer.class.getSimpleName() + " Timer"); - gameTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - tick(); - } - catch (Throwable ex) { - logger.error("Caught to prevent timer from shutting down", ex); - } - } - }, TICK_DELAY, TICK_DELAY); - } - - public static void stopTimer() { - if (gameTimer != null) { - gameTimer.cancel(); - } - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeUtils.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeUtils.java deleted file mode 100644 index b4426cd4830..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import java.awt.Color; -import java.util.Random; - -public final class SnakeUtils { - - /** - * The width of the playfield. - */ - public static final int PLAYFIELD_WIDTH = 640; - - /** - * The height of the playfield. - */ - public static final int PLAYFIELD_HEIGHT = 480; - - /** - * The grid size. - */ - public static final int GRID_SIZE = 10; - - private static final Random random = new Random(); - - private SnakeUtils() { - } - - public static String getRandomHexColor() { - float hue = random.nextFloat(); - // sat between 0.1 and 0.3 - float saturation = (random.nextInt(2000) + 1000) / 10000f; - float luminance = 0.9f; - Color color = Color.getHSBColor(hue, saturation, luminance); - return '#' + Integer.toHexString((color.getRGB() & 0xffffff) | 0x1000000).substring(1); - } - - public static Location getRandomLocation() { - int x = roundByGridSize(random.nextInt(PLAYFIELD_WIDTH)); - int y = roundByGridSize(random.nextInt(PLAYFIELD_HEIGHT)); - return new Location(x, y); - } - - private static int roundByGridSize(int value) { - value = value + (GRID_SIZE / 2); - value = value / GRID_SIZE; - value = value * GRID_SIZE; - return value; - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeWebSocketHandler.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeWebSocketHandler.java deleted file mode 100644 index f9175391905..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/SnakeWebSocketHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import java.awt.Color; -import java.util.Iterator; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import org.jspecify.annotations.Nullable; - -import org.springframework.util.Assert; -import org.springframework.web.socket.CloseStatus; -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketSession; -import org.springframework.web.socket.handler.TextWebSocketHandler; - -public class SnakeWebSocketHandler extends TextWebSocketHandler { - - private static final AtomicInteger snakeIds = new AtomicInteger(); - - private static final Random random = new Random(); - - private final int id; - - private @Nullable Snake snake; - - public static String getRandomHexColor() { - float hue = random.nextFloat(); - // sat between 0.1 and 0.3 - float saturation = (random.nextInt(2000) + 1000) / 10000f; - float luminance = 0.9f; - Color color = Color.getHSBColor(hue, saturation, luminance); - return '#' + Integer.toHexString((color.getRGB() & 0xffffff) | 0x1000000).substring(1); - } - - public static Location getRandomLocation() { - int x = roundByGridSize(random.nextInt(SnakeUtils.PLAYFIELD_WIDTH)); - int y = roundByGridSize(random.nextInt(SnakeUtils.PLAYFIELD_HEIGHT)); - return new Location(x, y); - } - - private static int roundByGridSize(int value) { - value = value + (SnakeUtils.GRID_SIZE / 2); - value = value / SnakeUtils.GRID_SIZE; - value = value * SnakeUtils.GRID_SIZE; - return value; - } - - public SnakeWebSocketHandler() { - this.id = snakeIds.getAndIncrement(); - } - - @Override - public void afterConnectionEstablished(WebSocketSession session) throws Exception { - this.snake = new Snake(this.id, session); - SnakeTimer.addSnake(this.snake); - StringBuilder sb = new StringBuilder(); - for (Iterator iterator = SnakeTimer.getSnakes().iterator(); iterator.hasNext();) { - Snake snake = iterator.next(); - sb.append(String.format("{id: %d, color: '%s'}", snake.getId(), snake.getHexColor())); - if (iterator.hasNext()) { - sb.append(','); - } - } - SnakeTimer.broadcast(String.format("{'type': 'join','data':[%s]}", sb)); - } - - @Override - protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { - Assert.state(this.snake != null, "'snake' must not be null"); - String payload = message.getPayload(); - switch (payload) { - case "west" -> this.snake.setDirection(Direction.WEST); - case "north" -> this.snake.setDirection(Direction.NORTH); - case "east" -> this.snake.setDirection(Direction.EAST); - case "south" -> this.snake.setDirection(Direction.SOUTH); - } - } - - @Override - public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { - Assert.state(this.snake != null, "'snake' must not be null"); - SnakeTimer.removeSnake(this.snake); - SnakeTimer.broadcast(String.format("{'type': 'leave', 'id': %d}", this.id)); - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/package-info.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/package-info.java deleted file mode 100644 index 06e4eedbc4b..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/java/smoketest/websocket/undertow/snake/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@NullMarked -package smoketest.websocket.undertow.snake; - -import org.jspecify.annotations.NullMarked; diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/echo.html b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/echo.html deleted file mode 100644 index 54d33f55bd8..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/echo.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - Apache Tomcat WebSocket Examples: Echo - - - - - - -
-
-
- -
-
- - -
-
- -
-
- -
-
-
-
-
-
- - diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/index.html b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/index.html deleted file mode 100644 index 6bab9d62379..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - Apache Tomcat WebSocket Examples: Index - - - -

Please select the sample you would like to try.

-
- - diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/reverse.html b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/reverse.html deleted file mode 100644 index 60d7ee49789..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/reverse.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - WebSocket Examples: Reverse - - - - - -
-
-
- -
-
- - -
-
- -
-
- -
-
-
-
-
-
- - diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/snake.html b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/snake.html deleted file mode 100644 index fe0a2ea88e0..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/main/resources/static/snake.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - - - Apache Tomcat WebSocket Examples: Multiplayer Snake - - - - - - -
- -
-
-
-
- - - diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java deleted file mode 100644 index 5a0498aaaec..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; -import smoketest.websocket.undertow.client.GreetingService; -import smoketest.websocket.undertow.client.SimpleClientWebSocketHandler; -import smoketest.websocket.undertow.client.SimpleGreetingService; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.client.WebSocketConnectionManager; -import org.springframework.web.socket.client.standard.StandardWebSocketClient; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(classes = SampleUndertowWebSocketsApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) -class SampleWebSocketsApplicationTests { - - private static final Log logger = LogFactory.getLog(SampleWebSocketsApplicationTests.class); - - @LocalServerPort - private int port = 1234; - - @Test - void echoEndpoint() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(ClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class) - .properties("websocket.uri:ws://localhost:" + this.port + "/echo/websocket") - .run("--spring.main.web-application-type=none"); - long count = context.getBean(ClientConfiguration.class).latch.getCount(); - AtomicReference messagePayloadReference = context.getBean(ClientConfiguration.class).messagePayload; - context.close(); - assertThat(count).isZero(); - assertThat(messagePayloadReference.get()).isEqualTo("Did you say \"Hello world!\"?"); - } - - @Test - void reverseEndpoint() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(ClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class) - .properties("websocket.uri:ws://localhost:" + this.port + "/reverse") - .run("--spring.main.web-application-type=none"); - long count = context.getBean(ClientConfiguration.class).latch.getCount(); - AtomicReference messagePayloadReference = context.getBean(ClientConfiguration.class).messagePayload; - context.close(); - assertThat(count).isZero(); - assertThat(messagePayloadReference.get()).isEqualTo("Reversed: !dlrow olleH"); - } - - @Configuration(proxyBeanMethods = false) - static class ClientConfiguration implements CommandLineRunner { - - @Value("${websocket.uri}") - private String webSocketUri; - - private final CountDownLatch latch = new CountDownLatch(1); - - private final AtomicReference messagePayload = new AtomicReference<>(); - - @Override - public void run(String... args) throws Exception { - logger.info("Waiting for response: latch=" + this.latch.getCount()); - if (this.latch.await(10, TimeUnit.SECONDS)) { - logger.info("Got response: " + this.messagePayload.get()); - } - else { - logger.info("Response not received: latch=" + this.latch.getCount()); - } - } - - @Bean - WebSocketConnectionManager wsConnectionManager() { - WebSocketConnectionManager manager = new WebSocketConnectionManager(client(), handler(), this.webSocketUri); - manager.setAutoStartup(true); - return manager; - } - - @Bean - StandardWebSocketClient client() { - return new StandardWebSocketClient(); - } - - @Bean - SimpleClientWebSocketHandler handler() { - return new SimpleClientWebSocketHandler(greetingService(), this.latch, this.messagePayload); - } - - @Bean - GreetingService greetingService() { - return new SimpleGreetingService(); - } - - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java deleted file mode 100644 index 77f105ea8f8..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.echo; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; -import smoketest.websocket.undertow.SampleUndertowWebSocketsApplication; -import smoketest.websocket.undertow.client.GreetingService; -import smoketest.websocket.undertow.client.SimpleClientWebSocketHandler; -import smoketest.websocket.undertow.client.SimpleGreetingService; -import smoketest.websocket.undertow.echo.CustomContainerWebSocketsApplicationTests.CustomContainerConfiguration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.servlet.ServletWebServerFactory; -import org.springframework.boot.web.server.test.LocalServerPort; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.client.WebSocketConnectionManager; -import org.springframework.web.socket.client.standard.StandardWebSocketClient; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(classes = { SampleUndertowWebSocketsApplication.class, CustomContainerConfiguration.class }, - webEnvironment = WebEnvironment.RANDOM_PORT) -class CustomContainerWebSocketsApplicationTests { - - private static final Log logger = LogFactory.getLog(CustomContainerWebSocketsApplicationTests.class); - - @LocalServerPort - private int port; - - @Test - void echoEndpoint() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(ClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class) - .properties("websocket.uri:ws://localhost:" + this.port + "/ws/echo/websocket") - .run("--spring.main.web-application-type=none"); - long count = context.getBean(ClientConfiguration.class).latch.getCount(); - AtomicReference messagePayloadReference = context.getBean(ClientConfiguration.class).messagePayload; - context.close(); - assertThat(count).isZero(); - assertThat(messagePayloadReference.get()).isEqualTo("Did you say \"Hello world!\"?"); - } - - @Test - void reverseEndpoint() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(ClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class) - .properties("websocket.uri:ws://localhost:" + this.port + "/ws/reverse") - .run("--spring.main.web-application-type=none"); - long count = context.getBean(ClientConfiguration.class).latch.getCount(); - AtomicReference messagePayloadReference = context.getBean(ClientConfiguration.class).messagePayload; - context.close(); - assertThat(count).isZero(); - assertThat(messagePayloadReference.get()).isEqualTo("Reversed: !dlrow olleH"); - } - - @Configuration(proxyBeanMethods = false) - protected static class CustomContainerConfiguration { - - @Bean - public ServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory("/ws", 0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ClientConfiguration implements CommandLineRunner { - - @Value("${websocket.uri}") - private String webSocketUri; - - private final CountDownLatch latch = new CountDownLatch(1); - - private final AtomicReference messagePayload = new AtomicReference<>(); - - @Override - public void run(String... args) throws Exception { - logger.info("Waiting for response: latch=" + this.latch.getCount()); - if (this.latch.await(10, TimeUnit.SECONDS)) { - logger.info("Got response: " + this.messagePayload.get()); - } - else { - logger.info("Response not received: latch=" + this.latch.getCount()); - } - } - - @Bean - WebSocketConnectionManager wsConnectionManager() { - - WebSocketConnectionManager manager = new WebSocketConnectionManager(client(), handler(), this.webSocketUri); - manager.setAutoStartup(true); - - return manager; - } - - @Bean - StandardWebSocketClient client() { - return new StandardWebSocketClient(); - } - - @Bean - SimpleClientWebSocketHandler handler() { - return new SimpleClientWebSocketHandler(greetingService(), this.latch, this.messagePayload); - } - - @Bean - GreetingService greetingService() { - return new SimpleGreetingService(); - } - - } - -} diff --git a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/snake/SnakeTimerTests.java b/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/snake/SnakeTimerTests.java deleted file mode 100644 index dc0db85af3a..00000000000 --- a/smoke-test/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/snake/SnakeTimerTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.websocket.undertow.snake; - -import java.io.IOException; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.willThrow; -import static org.mockito.Mockito.mock; - -class SnakeTimerTests { - - @Test - void removeDysfunctionalSnakes() throws Exception { - Snake snake = mock(Snake.class); - willThrow(new IOException()).given(snake).sendMessage(anyString()); - SnakeTimer.addSnake(snake); - SnakeTimer.broadcast(""); - assertThat(SnakeTimer.getSnakes()).isEmpty(); - } - -} diff --git a/starter/spring-boot-starter-undertow/build.gradle b/starter/spring-boot-starter-undertow/build.gradle deleted file mode 100644 index df9cba4387a..00000000000 --- a/starter/spring-boot-starter-undertow/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "org.springframework.boot.starter" -} - -description = "Starter for using Undertow" - -dependencies { - api(project(":starter:spring-boot-starter")) - - api(project(":module:spring-boot-undertow")) - - api("io.undertow:undertow-servlet") - api("io.undertow:undertow-websockets-jsr") - api("org.apache.tomcat.embed:tomcat-embed-el") -}