webflux-form sample uses Tomcat

Work around gh-4923
This commit is contained in:
Rob Winch 2017-12-20 15:08:38 -06:00
parent 268a1dc06e
commit 67bb91bb76
3 changed files with 37 additions and 15 deletions

View File

@ -20,9 +20,8 @@ dependencies {
compile project(':spring-security-core') compile project(':spring-security-core')
compile project(':spring-security-config') compile project(':spring-security-config')
compile project(':spring-security-web') compile project(':spring-security-web')
compile 'org.apache.tomcat.embed:tomcat-embed-core'
compile 'com.fasterxml.jackson.core:jackson-databind' compile 'com.fasterxml.jackson.core:jackson-databind'
compile 'io.netty:netty-buffer'
compile 'io.projectreactor.ipc:reactor-netty'
compile 'org.springframework:spring-context' compile 'org.springframework:spring-context'
compile 'org.springframework:spring-webflux' compile 'org.springframework:spring-webflux'
compile 'org.thymeleaf:thymeleaf-spring5' compile 'org.thymeleaf:thymeleaf-spring5'

View File

@ -28,17 +28,20 @@ import org.springframework.test.context.junit4.SpringRunner;
import sample.webdriver.IndexPage; import sample.webdriver.IndexPage;
import sample.webdriver.LoginPage; import sample.webdriver.LoginPage;
import java.io.IOException;
import java.net.ServerSocket;
/** /**
* @author Rob Winch * @author Rob Winch
* @since 5.0 * @since 5.0
*/ */
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@ContextConfiguration(classes = WebfluxFormApplication.class) @ContextConfiguration(classes = WebfluxFormApplication.class)
@TestPropertySource(properties = "server.port=0") @TestPropertySource(properties = "server.port=#{T(sample.WebfluxFormApplicationTests).availablePort()}")
public class WebfluxFormApplicationTests { public class WebfluxFormApplicationTests {
WebDriver driver; WebDriver driver;
@Value("#{@nettyContext.address().getPort()}") @Value("#{@tomcat.server.port}")
int port; int port;
@Before @Before
@ -76,4 +79,12 @@ public class WebfluxFormApplicationTests {
.assertAt() .assertAt()
.assertLogout(); .assertLogout();
} }
public static final int availablePort() {
try(ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
} catch(IOException e) {
throw new RuntimeException(e);
}
}
} }

View File

@ -16,15 +16,20 @@
package sample; package sample;
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import reactor.ipc.netty.NettyContext;
import reactor.ipc.netty.http.server.HttpServer; import javax.servlet.Servlet;
/** /**
* @author Rob Winch * @author Rob Winch
@ -38,19 +43,26 @@ public class WebfluxFormApplication {
private int port = 8080; private int port = 8080;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Object lock = new Object();
try(AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( try(AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
WebfluxFormApplication.class)) { WebfluxFormApplication.class)) {
context.getBean(NettyContext.class).onClose().block(); synchronized (lock) {
lock.wait();
}
} }
} }
@Profile("default") @Bean(destroyMethod = "stop", initMethod = "start")
@Bean public Tomcat tomcat(ApplicationContext context) throws Exception {
public NettyContext nettyContext(ApplicationContext context) {
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context) HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
.build(); .build();
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler); Servlet servlet = new ServletHttpHandlerAdapter(handler);
HttpServer httpServer = HttpServer.create("localhost", port); Tomcat server = new Tomcat();
return httpServer.newHandler(adapter).block(); server.setPort(this.port);
server.getServer().setPort(this.port);
Context rootContext = server.addContext("", System.getProperty("java.io.tmpdir"));
Tomcat.addServlet(rootContext, "servlet", servlet);
rootContext.addServletMapping("/", "servlet");
return server;
} }
} }