parent
c501b889af
commit
1864d79077
|
@ -29,4 +29,3 @@ overridedb.*
|
||||||
*.iws
|
*.iws
|
||||||
.idea
|
.idea
|
||||||
*.jar
|
*.jar
|
||||||
.DS_Store
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ -106,7 +107,6 @@ public class EmbeddedServletContainerAutoConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a {@link EmbeddedServletContainerCustomizerBeanPostProcessor}. Registered
|
* Registers a {@link EmbeddedServletContainerCustomizerBeanPostProcessor}. Registered
|
||||||
* via {@link ImportBeanDefinitionRegistrar} for early registration.
|
* via {@link ImportBeanDefinitionRegistrar} for early registration.
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = false)
|
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = false)
|
||||||
public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||||
|
@ -220,62 +221,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||||
return prefix + path;
|
return prefix + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Undertow {
|
|
||||||
private Integer bufferSize;
|
|
||||||
private Integer buffersPerRegion;
|
|
||||||
private Integer ioThreads;
|
|
||||||
private Integer workerThreads;
|
|
||||||
private Boolean directBuffers;
|
|
||||||
|
|
||||||
public Integer getBufferSize() {
|
|
||||||
return this.bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBufferSize(Integer bufferSize) {
|
|
||||||
this.bufferSize = bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getBuffersPerRegion() {
|
|
||||||
return this.buffersPerRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBuffersPerRegion(Integer buffersPerRegion) {
|
|
||||||
this.buffersPerRegion = buffersPerRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getIoThreads() {
|
|
||||||
return this.ioThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIoThreads(Integer ioThreads) {
|
|
||||||
this.ioThreads = ioThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getWorkerThreads() {
|
|
||||||
return this.workerThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWorkerThreads(Integer workerThreads) {
|
|
||||||
this.workerThreads = workerThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getDirectBuffers() {
|
|
||||||
return this.directBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDirectBuffers(Boolean directBuffers) {
|
|
||||||
this.directBuffers = directBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void customizeUndertow(UndertowEmbeddedServletContainerFactory factory) {
|
|
||||||
factory.setBufferSize(bufferSize);
|
|
||||||
factory.setBuffersPerRegion(buffersPerRegion);
|
|
||||||
factory.setIoThreads(ioThreads);
|
|
||||||
factory.setWorkerThreads(workerThreads);
|
|
||||||
factory.setDirectBuffers(directBuffers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Tomcat {
|
public static class Tomcat {
|
||||||
|
|
||||||
private String accessLogPattern;
|
private String accessLogPattern;
|
||||||
|
@ -462,4 +407,66 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Undertow {
|
||||||
|
|
||||||
|
private Integer bufferSize;
|
||||||
|
|
||||||
|
private Integer buffersPerRegion;
|
||||||
|
|
||||||
|
private Integer ioThreads;
|
||||||
|
|
||||||
|
private Integer workerThreads;
|
||||||
|
|
||||||
|
private Boolean directBuffers;
|
||||||
|
|
||||||
|
public Integer getBufferSize() {
|
||||||
|
return this.bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBufferSize(Integer bufferSize) {
|
||||||
|
this.bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBuffersPerRegion() {
|
||||||
|
return this.buffersPerRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBuffersPerRegion(Integer buffersPerRegion) {
|
||||||
|
this.buffersPerRegion = buffersPerRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getIoThreads() {
|
||||||
|
return this.ioThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIoThreads(Integer ioThreads) {
|
||||||
|
this.ioThreads = ioThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getWorkerThreads() {
|
||||||
|
return this.workerThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerThreads(Integer workerThreads) {
|
||||||
|
this.workerThreads = workerThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getDirectBuffers() {
|
||||||
|
return this.directBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectBuffers(Boolean directBuffers) {
|
||||||
|
this.directBuffers = directBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void customizeUndertow(UndertowEmbeddedServletContainerFactory factory) {
|
||||||
|
factory.setBufferSize(this.bufferSize);
|
||||||
|
factory.setBuffersPerRegion(this.buffersPerRegion);
|
||||||
|
factory.setIoThreads(this.ioThreads);
|
||||||
|
factory.setWorkerThreads(this.workerThreads);
|
||||||
|
factory.setDirectBuffers(this.directBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web;
|
package org.springframework.boot.autoconfigure.web;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
|
|
||||||
import javax.servlet.MultipartConfigElement;
|
import javax.servlet.MultipartConfigElement;
|
||||||
|
|
||||||
|
@ -65,6 +63,7 @@ import static org.mockito.Mockito.mock;
|
||||||
* @author Greg Turnquist
|
* @author Greg Turnquist
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Josh Long
|
* @author Josh Long
|
||||||
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
public class MultipartAutoConfigurationTests {
|
public class MultipartAutoConfigurationTests {
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ import static org.mockito.Mockito.verify;
|
||||||
* Tests for {@link ServerPropertiesAutoConfiguration}.
|
* Tests for {@link ServerPropertiesAutoConfiguration}.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
public class ServerPropertiesAutoConfigurationTests {
|
public class ServerPropertiesAutoConfigurationTests {
|
||||||
|
|
||||||
|
@ -113,7 +114,6 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||||
assertEquals(3000, containerFactory.getPort());
|
assertEquals(3000, containerFactory.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void customizeWithUndertowContainerFactory() throws Exception {
|
public void customizeWithUndertowContainerFactory() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||||
|
@ -128,7 +128,6 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||||
assertEquals(3000, containerFactory.getPort());
|
assertEquals(3000, containerFactory.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void customizeTomcatWithCustomizer() throws Exception {
|
public void customizeTomcatWithCustomizer() throws Exception {
|
||||||
containerFactory = mock(TomcatEmbeddedServletContainerFactory.class);
|
containerFactory = mock(TomcatEmbeddedServletContainerFactory.class);
|
||||||
|
@ -204,9 +203,6 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class CustomizeConfig {
|
protected static class CustomizeConfig {
|
||||||
|
|
||||||
|
|
|
@ -127,10 +127,10 @@
|
||||||
<thymeleaf-layout-dialect.version>1.2.7</thymeleaf-layout-dialect.version>
|
<thymeleaf-layout-dialect.version>1.2.7</thymeleaf-layout-dialect.version>
|
||||||
<thymeleaf-extras-data-attribute.version>1.3</thymeleaf-extras-data-attribute.version>
|
<thymeleaf-extras-data-attribute.version>1.3</thymeleaf-extras-data-attribute.version>
|
||||||
<tomcat.version>8.0.15</tomcat.version>
|
<tomcat.version>8.0.15</tomcat.version>
|
||||||
|
<undertow.version>1.1.0.Final</undertow.version>
|
||||||
<velocity.version>1.7</velocity.version>
|
<velocity.version>1.7</velocity.version>
|
||||||
<velocity-tools.version>2.0</velocity-tools.version>
|
<velocity-tools.version>2.0</velocity-tools.version>
|
||||||
<wsdl4j.version>1.6.3</wsdl4j.version>
|
<wsdl4j.version>1.6.3</wsdl4j.version>
|
||||||
<undertow.version>1.1.0.Final</undertow.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
<prerequisites>
|
<prerequisites>
|
||||||
<maven>3.0.2</maven>
|
<maven>3.0.2</maven>
|
||||||
|
@ -540,6 +540,16 @@
|
||||||
<artifactId>metrics-servlets</artifactId>
|
<artifactId>metrics-servlets</artifactId>
|
||||||
<version>${dropwizard-metrics.version}</version>
|
<version>${dropwizard-metrics.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.undertow</groupId>
|
||||||
|
<artifactId>undertow-core</artifactId>
|
||||||
|
<version>${undertow.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.undertow</groupId>
|
||||||
|
<artifactId>undertow-servlet</artifactId>
|
||||||
|
<version>${undertow.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.cache</groupId>
|
<groupId>javax.cache</groupId>
|
||||||
<artifactId>cache-api</artifactId>
|
<artifactId>cache-api</artifactId>
|
||||||
|
@ -707,11 +717,6 @@
|
||||||
<artifactId>tomcat-jsp-api</artifactId>
|
<artifactId>tomcat-jsp-api</artifactId>
|
||||||
<version>${tomcat.version}</version>
|
<version>${tomcat.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.undertow</groupId>
|
|
||||||
<artifactId>undertow-servlet</artifactId>
|
|
||||||
<version>${undertow.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity</artifactId>
|
||||||
|
|
|
@ -158,8 +158,8 @@ for our starter REST application:
|
||||||
|
|
||||||
Spring Boot makes `-D` arguments available as properties accessible from a Spring
|
Spring Boot makes `-D` arguments available as properties accessible from a Spring
|
||||||
`Environment` instance. The `server.port` configuration property is fed to the embedded
|
`Environment` instance. The `server.port` configuration property is fed to the embedded
|
||||||
Tomcat or Jetty instance which then uses it when it starts up. The `$PORT` environment
|
Tomcat, Jetty or Undertow instance which then uses it when it starts up. The `$PORT`
|
||||||
variable is assigned to us by the Heroku PaaS.
|
environment variable is assigned to us by the Heroku PaaS.
|
||||||
|
|
||||||
Heroku by default will use Java 1.6. This is fine as long as your Maven or Gradle build
|
Heroku by default will use Java 1.6. This is fine as long as your Maven or Gradle build
|
||||||
is set to use the same version (Maven users can use the `java.version` property). If you
|
is set to use the same version (Maven users can use the `java.version` property). If you
|
||||||
|
|
|
@ -556,6 +556,61 @@ of ways. Or the nuclear option is to add your own `JettyEmbeddedServletContainer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[howto-use-undertow-instead-of-tomcat]]
|
||||||
|
=== Use Undertow instead of Tomcat
|
||||||
|
Using Undertow instead of Tomcat is very similar to <<howto-use-jetty-instead-of-tomcat,
|
||||||
|
using Jetty instead of Tomcat>>. You need to exclude the Tomcat dependencies and include
|
||||||
|
the Undertow starter instead.
|
||||||
|
|
||||||
|
Example in Maven:
|
||||||
|
|
||||||
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||||
|
----
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||||
|
</dependency>
|
||||||
|
----
|
||||||
|
|
||||||
|
Example in Gradle:
|
||||||
|
|
||||||
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
||||||
|
----
|
||||||
|
configurations {
|
||||||
|
compile.exclude module: "spring-boot-starter-tomcat"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
|
||||||
|
compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}")
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
[[howto-configure-undertow]]
|
||||||
|
=== Configure Undertow
|
||||||
|
Generally you can follow the advice from
|
||||||
|
_<<howto-discover-build-in-options-for-external-properties>>_ about
|
||||||
|
`@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow are the
|
||||||
|
main ones here), but also look at
|
||||||
|
`EmbeddedServletContainerCustomizer`. Once you have access to the
|
||||||
|
`UndertowEmbeddedServletContainerFactory` you can use an `UndertowBuilderCustomizer` to
|
||||||
|
modify Undertow's configuration to meet your needs. Or the nuclear option is to add your
|
||||||
|
own `UndertowEmbeddedServletContainerFactory`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-use-tomcat-8]]
|
[[howto-use-tomcat-8]]
|
||||||
=== Use Tomcat 8
|
=== Use Tomcat 8
|
||||||
Tomcat 8 works with Spring Boot, but the default is to use Tomcat 7 (so we can support
|
Tomcat 8 works with Spring Boot, but the default is to use Tomcat 7 (so we can support
|
||||||
|
|
|
@ -810,8 +810,8 @@ possible.
|
||||||
[[boot-features-developing-web-applications]]
|
[[boot-features-developing-web-applications]]
|
||||||
== Developing web applications
|
== Developing web applications
|
||||||
Spring Boot is well suited for web application development. You can easily create a
|
Spring Boot is well suited for web application development. You can easily create a
|
||||||
self-contained HTTP server using embedded Tomcat or Jetty. Most web applications will
|
self-contained HTTP server using embedded Tomcat, Jetty, or Undertow. Most web
|
||||||
use the `spring-boot-starter-web` module to get up and running quickly.
|
applications will use the `spring-boot-starter-web` module to get up and running quickly.
|
||||||
|
|
||||||
If you haven't yet developed a Spring Boot web application you can follow the
|
If you haven't yet developed a Spring Boot web application you can follow the
|
||||||
"Hello World!" example in the
|
"Hello World!" example in the
|
||||||
|
@ -1093,9 +1093,9 @@ asks for them to be scanned in its `Filter` registration).
|
||||||
|
|
||||||
[[boot-features-embedded-container]]
|
[[boot-features-embedded-container]]
|
||||||
=== Embedded servlet container support
|
=== Embedded servlet container support
|
||||||
Spring Boot includes support for embedded Tomcat and Jetty servers. Most developers will
|
Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most
|
||||||
simply use the appropriate '`Starter POM`' to obtain a fully configured instance. By
|
developers will simply use the appropriate '`Starter POM`' to obtain a fully configured
|
||||||
default both Tomcat and Jetty will listen for HTTP requests on port `8080`.
|
instance. By default the embedded server will listen for HTTP requests on port `8080`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1121,8 +1121,9 @@ interface.
|
||||||
Under the hood Spring Boot uses a new type of `ApplicationContext` for embedded
|
Under the hood Spring Boot uses a new type of `ApplicationContext` for embedded
|
||||||
servlet container support. The `EmbeddedWebApplicationContext` is a special
|
servlet container support. The `EmbeddedWebApplicationContext` is a special
|
||||||
type of `WebApplicationContext` that bootstraps itself by searching for a single
|
type of `WebApplicationContext` that bootstraps itself by searching for a single
|
||||||
`EmbeddedServletContainerFactory` bean. Usually a `TomcatEmbeddedServletContainerFactory`
|
`EmbeddedServletContainerFactory` bean. Usually a `TomcatEmbeddedServletContainerFactory`,
|
||||||
or `JettyEmbeddedServletContainerFactory` will have been auto-configured.
|
`JettyEmbeddedServletContainerFactory`, or `UndertowEmbeddedServletContainerFactory` will
|
||||||
|
have been auto-configured.
|
||||||
|
|
||||||
NOTE: You usually won't need to be aware of these implementation classes. Most
|
NOTE: You usually won't need to be aware of these implementation classes. Most
|
||||||
applications will be auto-configured and the appropriate `ApplicationContext` and
|
applications will be auto-configured and the appropriate `ApplicationContext` and
|
||||||
|
@ -1176,8 +1177,8 @@ methods.
|
||||||
[[boot-features-customizing-configurableembeddedservletcontainerfactory-directly]]
|
[[boot-features-customizing-configurableembeddedservletcontainerfactory-directly]]
|
||||||
===== Customizing ConfigurableEmbeddedServletContainer directly
|
===== Customizing ConfigurableEmbeddedServletContainer directly
|
||||||
If the above customization techniques are too limited, you can register the
|
If the above customization techniques are too limited, you can register the
|
||||||
`TomcatEmbeddedServletContainerFactory` or `JettyEmbeddedServletContainerFactory` bean
|
`TomcatEmbeddedServletContainerFactory`, `JettyEmbeddedServletContainerFactory` or
|
||||||
yourself.
|
`UndertowEmbeddedServletContainerFactory` bean yourself.
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
|
@ -1208,6 +1209,8 @@ packaged as an executable archive), there are some limitations in the JSP suppor
|
||||||
|
|
||||||
* Jetty does not currently work as an embedded container with JSPs.
|
* Jetty does not currently work as an embedded container with JSPs.
|
||||||
|
|
||||||
|
* Undertow does not support JSPs
|
||||||
|
|
||||||
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so
|
||||||
you can see how to set things up.
|
you can see how to set things up.
|
||||||
|
|
||||||
|
|
|
@ -348,6 +348,9 @@ swap specific technical facets.
|
||||||
|
|
||||||
|`spring-boot-starter-tomcat`
|
|`spring-boot-starter-tomcat`
|
||||||
|Import Spring Boot's default HTTP engine (Tomcat).
|
|Import Spring Boot's default HTTP engine (Tomcat).
|
||||||
|
|
||||||
|
|`spring-boot-starter-undertow`
|
||||||
|
|Imports the Undertow HTTP engine (to be used as an alternative to Tomcat)
|
||||||
|===
|
|===
|
||||||
|
|
||||||
TIP: For a list of additional community contributed starter POMs, see the
|
TIP: For a list of additional community contributed starter POMs, see the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -39,7 +39,7 @@ import static org.junit.Assert.assertEquals;
|
||||||
/**
|
/**
|
||||||
* Basic integration tests for demo application.
|
* Basic integration tests for demo application.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringApplicationConfiguration(classes = SampleUndertowSslApplication.class)
|
@SpringApplicationConfiguration(classes = SampleUndertowSslApplication.class)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2013 the original author or authors.
|
* Copyright 2012-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -19,9 +19,23 @@
|
||||||
<main.basedir>${basedir}/../..</main.basedir>
|
<main.basedir>${basedir}/../..</main.basedir>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.undertow</groupId>
|
||||||
|
<artifactId>undertow-core</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.undertow</groupId>
|
<groupId>io.undertow</groupId>
|
||||||
<artifactId>undertow-servlet</artifactId>
|
<artifactId>undertow-servlet</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||||
|
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.undertow;
|
||||||
|
|
||||||
|
import io.undertow.Undertow.Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback interface that can be used to customize an Undertow {@link Builder}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 1.2.0
|
||||||
|
* @see UndertowEmbeddedServletContainerFactory
|
||||||
|
*/
|
||||||
|
public interface UndertowBuilderCustomizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param builder the {@code Builder} to customize
|
||||||
|
*/
|
||||||
|
void customize(Builder builder);
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.undertow;
|
package org.springframework.boot.context.embedded.undertow;
|
||||||
|
|
||||||
import io.undertow.Handlers;
|
import io.undertow.Handlers;
|
||||||
|
@ -14,16 +30,29 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainerExcepti
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@link EmbeddedServletContainer} that can be used to control an embedded Undertow
|
||||||
|
* server. Typically this class should be created using
|
||||||
|
* {@link UndertowEmbeddedServletContainerFactory} and not directly.
|
||||||
|
*
|
||||||
* @author Ivan Sopov
|
* @author Ivan Sopov
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 1.2.0
|
||||||
|
* @see UndertowEmbeddedServletContainer
|
||||||
*/
|
*/
|
||||||
public class UndertowEmbeddedServletContainer implements EmbeddedServletContainer {
|
public class UndertowEmbeddedServletContainer implements EmbeddedServletContainer {
|
||||||
|
|
||||||
private final DeploymentManager manager;
|
private final DeploymentManager manager;
|
||||||
|
|
||||||
private final Builder builder;
|
private final Builder builder;
|
||||||
|
|
||||||
private final String contextPath;
|
private final String contextPath;
|
||||||
|
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
private final boolean autoStart;
|
private final boolean autoStart;
|
||||||
|
|
||||||
private Undertow undertow;
|
private Undertow undertow;
|
||||||
|
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
|
|
||||||
public UndertowEmbeddedServletContainer(Builder builder, DeploymentManager manager,
|
public UndertowEmbeddedServletContainer(Builder builder, DeploymentManager manager,
|
||||||
|
@ -40,38 +69,39 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
|
||||||
if (!this.autoStart) {
|
if (!this.autoStart) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (undertow == null) {
|
if (this.undertow == null) {
|
||||||
try {
|
try {
|
||||||
HttpHandler servletHandler = manager.start();
|
HttpHandler servletHandler = this.manager.start();
|
||||||
if (StringUtils.isEmpty(contextPath)) {
|
if (StringUtils.isEmpty(this.contextPath)) {
|
||||||
builder.setHandler(servletHandler);
|
this.builder.setHandler(servletHandler);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PathHandler pathHandler = Handlers.path().addPrefixPath(contextPath,
|
PathHandler pathHandler = Handlers.path().addPrefixPath(
|
||||||
servletHandler);
|
this.contextPath, servletHandler);
|
||||||
builder.setHandler(pathHandler);
|
this.builder.setHandler(pathHandler);
|
||||||
}
|
}
|
||||||
undertow = builder.build();
|
this.undertow = this.builder.build();
|
||||||
}
|
}
|
||||||
catch (ServletException ex) {
|
catch (ServletException ex) {
|
||||||
throw new EmbeddedServletContainerException(
|
throw new EmbeddedServletContainerException(
|
||||||
"Unable to start embdedded Undertow", ex);
|
"Unable to start embdedded Undertow", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
undertow.start();
|
this.undertow.start();
|
||||||
started = true;
|
this.started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void stop() throws EmbeddedServletContainerException {
|
public synchronized void stop() throws EmbeddedServletContainerException {
|
||||||
if (started) {
|
if (this.started) {
|
||||||
started = false;
|
this.started = false;
|
||||||
undertow.stop();
|
this.undertow.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPort() {
|
public int getPort() {
|
||||||
return port;
|
return this.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,12 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.undertow;
|
package org.springframework.boot.context.embedded.undertow;
|
||||||
|
|
||||||
import static io.undertow.servlet.Servlets.defaultContainer;
|
|
||||||
import static io.undertow.servlet.Servlets.deployment;
|
|
||||||
import static io.undertow.servlet.Servlets.servlet;
|
|
||||||
import static org.xnio.Options.SSL_CLIENT_AUTH_MODE;
|
|
||||||
import static org.xnio.SslClientAuthMode.NOT_REQUESTED;
|
|
||||||
import static org.xnio.SslClientAuthMode.REQUESTED;
|
|
||||||
import static org.xnio.SslClientAuthMode.REQUIRED;
|
|
||||||
import io.undertow.Undertow;
|
import io.undertow.Undertow;
|
||||||
import io.undertow.Undertow.Builder;
|
import io.undertow.Undertow.Builder;
|
||||||
import io.undertow.UndertowMessages;
|
import io.undertow.UndertowMessages;
|
||||||
|
@ -27,12 +36,15 @@ import io.undertow.servlet.handlers.DefaultServlet;
|
||||||
import io.undertow.servlet.util.ImmediateInstanceHandle;
|
import io.undertow.servlet.util.ImmediateInstanceHandle;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.net.ssl.KeyManager;
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
|
@ -45,6 +57,7 @@ import javax.servlet.ServletException;
|
||||||
|
|
||||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||||
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
||||||
|
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||||
import org.springframework.boot.context.embedded.ErrorPage;
|
import org.springframework.boot.context.embedded.ErrorPage;
|
||||||
import org.springframework.boot.context.embedded.MimeMappings.Mapping;
|
import org.springframework.boot.context.embedded.MimeMappings.Mapping;
|
||||||
import org.springframework.boot.context.embedded.ServletContextInitializer;
|
import org.springframework.boot.context.embedded.ServletContextInitializer;
|
||||||
|
@ -52,156 +65,162 @@ import org.springframework.boot.context.embedded.Ssl;
|
||||||
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
|
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
import org.springframework.util.SocketUtils;
|
import org.springframework.util.SocketUtils;
|
||||||
|
|
||||||
|
import static io.undertow.servlet.Servlets.defaultContainer;
|
||||||
|
import static io.undertow.servlet.Servlets.deployment;
|
||||||
|
import static io.undertow.servlet.Servlets.servlet;
|
||||||
|
import static org.xnio.Options.SSL_CLIENT_AUTH_MODE;
|
||||||
|
import static org.xnio.SslClientAuthMode.NOT_REQUESTED;
|
||||||
|
import static org.xnio.SslClientAuthMode.REQUESTED;
|
||||||
|
import static org.xnio.SslClientAuthMode.REQUIRED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@link EmbeddedServletContainerFactory} that can be used to create
|
||||||
|
* {@link UndertowEmbeddedServletContainer}s.
|
||||||
|
* <p>
|
||||||
|
* Unless explicitly configured otherwise, the factory will create containers that listen
|
||||||
|
* for HTTP requests on port 8080.
|
||||||
|
*
|
||||||
* @author Ivan Sopov
|
* @author Ivan Sopov
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 1.2.0
|
||||||
|
* @see UndertowEmbeddedServletContainer
|
||||||
*/
|
*/
|
||||||
public class UndertowEmbeddedServletContainerFactory extends
|
public class UndertowEmbeddedServletContainerFactory extends
|
||||||
AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware {
|
AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware {
|
||||||
|
|
||||||
|
private List<UndertowBuilderCustomizer> undertowBuilderCustomizers = new ArrayList<UndertowBuilderCustomizer>();
|
||||||
|
|
||||||
private ResourceLoader resourceLoader;
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
private Integer bufferSize;
|
private Integer bufferSize;
|
||||||
|
|
||||||
private Integer buffersPerRegion;
|
private Integer buffersPerRegion;
|
||||||
|
|
||||||
private Integer ioThreads;
|
private Integer ioThreads;
|
||||||
|
|
||||||
private Integer workerThreads;
|
private Integer workerThreads;
|
||||||
|
|
||||||
private Boolean directBuffers;
|
private Boolean directBuffers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new
|
* Create a new {@link UndertowEmbeddedServletContainerFactory} instance.
|
||||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
|
||||||
* instance.
|
|
||||||
*/
|
*/
|
||||||
public UndertowEmbeddedServletContainerFactory() {
|
public UndertowEmbeddedServletContainerFactory() {
|
||||||
super();
|
super();
|
||||||
|
setRegisterJspServlet(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new
|
* Create a new {@link UndertowEmbeddedServletContainerFactory} that listens for
|
||||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
* requests using the specified port.
|
||||||
* that listens for requests using the specified port.
|
|
||||||
*
|
|
||||||
* @param port the port to listen on
|
* @param port the port to listen on
|
||||||
*/
|
*/
|
||||||
public UndertowEmbeddedServletContainerFactory(int port) {
|
public UndertowEmbeddedServletContainerFactory(int port) {
|
||||||
super(port);
|
super(port);
|
||||||
|
setRegisterJspServlet(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new
|
* Create a new {@link UndertowEmbeddedServletContainerFactory} with the specified
|
||||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
* context path and port.
|
||||||
* with the specified context path and port.
|
|
||||||
*
|
|
||||||
* @param contextPath root the context path
|
* @param contextPath root the context path
|
||||||
* @param port the port to listen on
|
* @param port the port to listen on
|
||||||
*/
|
*/
|
||||||
public UndertowEmbeddedServletContainerFactory(String contextPath, int port) {
|
public UndertowEmbeddedServletContainerFactory(String contextPath, int port) {
|
||||||
super(contextPath, port);
|
super(contextPath, port);
|
||||||
|
setRegisterJspServlet(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow
|
||||||
|
* {@link Builder}. Calling this method will replace any existing customizers.
|
||||||
|
* @param undertowBuilderCustomizers the customizers to set
|
||||||
|
*/
|
||||||
|
public void setUndertowBuilderCustomizers(
|
||||||
|
Collection<? extends UndertowBuilderCustomizer> undertowBuilderCustomizers) {
|
||||||
|
Assert.notNull(undertowBuilderCustomizers,
|
||||||
|
"undertowBuilderCustomizers must not be null");
|
||||||
|
this.undertowBuilderCustomizers = new ArrayList<UndertowBuilderCustomizer>(
|
||||||
|
undertowBuilderCustomizers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be
|
||||||
|
* applied to the Undertow {@link Builder} .
|
||||||
|
* @return the customizers that will be applied
|
||||||
|
*/
|
||||||
|
public Collection<UndertowBuilderCustomizer> getUndertowBuilderCustomizers() {
|
||||||
|
return this.undertowBuilderCustomizers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link UndertowBuilderCustomizer}s that should be used to customize the
|
||||||
|
* Undertow {@link Builder}.
|
||||||
|
* @param undertowBuilderCustomizers the customizers to add
|
||||||
|
*/
|
||||||
|
public void addUndertowBuilderCustomizers(
|
||||||
|
UndertowBuilderCustomizer... undertowBuilderCustomizers) {
|
||||||
|
Assert.notNull(undertowBuilderCustomizers,
|
||||||
|
"undertowBuilderCustomizers must not be null");
|
||||||
|
this.undertowBuilderCustomizers.addAll(Arrays.asList(undertowBuilderCustomizers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmbeddedServletContainer getEmbeddedServletContainer(
|
public EmbeddedServletContainer getEmbeddedServletContainer(
|
||||||
ServletContextInitializer... initializers) {
|
ServletContextInitializer... initializers) {
|
||||||
DeploymentInfo servletBuilder = deployment();
|
DeploymentManager manager = createDeploymentManager(initializers);
|
||||||
|
|
||||||
servletBuilder.addListener(new ListenerInfo(
|
int port = getPort();
|
||||||
UndertowSpringServletContextListener.class,
|
if (port == 0) {
|
||||||
new UndertowSpringServletContextListenerFactory(
|
port = SocketUtils.findAvailableTcpPort(40000);
|
||||||
new UndertowSpringServletContextListener(
|
|
||||||
mergeInitializers(initializers)))));
|
|
||||||
|
|
||||||
if (resourceLoader != null) {
|
|
||||||
servletBuilder.setClassLoader(resourceLoader.getClassLoader());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
servletBuilder.setClassLoader(getClass().getClassLoader());
|
|
||||||
}
|
|
||||||
servletBuilder.setContextPath(getContextPath());
|
|
||||||
servletBuilder.setDeploymentName("spring-boot");
|
|
||||||
if (isRegisterDefaultServlet()) {
|
|
||||||
servletBuilder.addServlet(servlet("default", DefaultServlet.class));
|
|
||||||
}
|
|
||||||
if (isRegisterJspServlet()) {
|
|
||||||
logger.error("JSPs are not supported with Undertow");
|
|
||||||
}
|
|
||||||
for (ErrorPage springErrorPage : getErrorPages()) {
|
|
||||||
if (springErrorPage.getStatus() != null) {
|
|
||||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
|
||||||
springErrorPage.getPath(), springErrorPage.getStatusCode());
|
|
||||||
servletBuilder.addErrorPage(undertowErrorpage);
|
|
||||||
}
|
|
||||||
else if (springErrorPage.getException() != null) {
|
|
||||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
|
||||||
springErrorPage.getPath(), springErrorPage.getException());
|
|
||||||
servletBuilder.addErrorPage(undertowErrorpage);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
|
||||||
springErrorPage.getPath());
|
|
||||||
servletBuilder.addErrorPage(undertowErrorpage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
servletBuilder.setServletStackTraces(ServletStackTraces.NONE);
|
|
||||||
|
|
||||||
File root = getValidDocumentRoot();
|
|
||||||
if (root != null && root.isDirectory()) {
|
|
||||||
servletBuilder.setResourceManager(new FileResourceManager(root, 0));
|
|
||||||
}
|
|
||||||
else if (root != null && root.isFile()) {
|
|
||||||
servletBuilder.setResourceManager(new JarResourcemanager(root));
|
|
||||||
}
|
|
||||||
else if (resourceLoader != null) {
|
|
||||||
servletBuilder.setResourceManager(new ClassPathResourceManager(resourceLoader
|
|
||||||
.getClassLoader(), ""));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
servletBuilder.setResourceManager(new ClassPathResourceManager(getClass()
|
|
||||||
.getClassLoader(), ""));
|
|
||||||
}
|
|
||||||
for (Mapping mimeMapping : getMimeMappings()) {
|
|
||||||
servletBuilder.addMimeMapping(new MimeMapping(mimeMapping.getExtension(),
|
|
||||||
mimeMapping.getMimeType()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
|
Builder builder = createBuilder(port);
|
||||||
|
|
||||||
manager.deploy();
|
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
||||||
|
port, port >= 0);
|
||||||
manager.getDeployment().getSessionManager()
|
}
|
||||||
.setDefaultSessionTimeout(getSessionTimeout());
|
|
||||||
|
|
||||||
|
private Builder createBuilder(int port) {
|
||||||
Builder builder = Undertow.builder();
|
Builder builder = Undertow.builder();
|
||||||
if (bufferSize != null) {
|
if (this.bufferSize != null) {
|
||||||
builder.setBufferSize(bufferSize);
|
builder.setBufferSize(this.bufferSize);
|
||||||
}
|
}
|
||||||
if (buffersPerRegion != null) {
|
if (this.buffersPerRegion != null) {
|
||||||
builder.setBuffersPerRegion(buffersPerRegion);
|
builder.setBuffersPerRegion(this.buffersPerRegion);
|
||||||
}
|
}
|
||||||
if (ioThreads != null) {
|
if (this.ioThreads != null) {
|
||||||
builder.setIoThreads(ioThreads);
|
builder.setIoThreads(this.ioThreads);
|
||||||
}
|
}
|
||||||
if (workerThreads != null) {
|
if (this.workerThreads != null) {
|
||||||
builder.setWorkerThreads(workerThreads);
|
builder.setWorkerThreads(this.workerThreads);
|
||||||
}
|
}
|
||||||
if (directBuffers != null) {
|
if (this.directBuffers != null) {
|
||||||
builder.setDirectBuffers(directBuffers);
|
builder.setDirectBuffers(this.directBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int realPort = getPort();
|
|
||||||
if (realPort == 0) {
|
|
||||||
realPort = SocketUtils.findAvailableTcpPort(40000);
|
|
||||||
}
|
|
||||||
if (getSsl() == null) {
|
if (getSsl() == null) {
|
||||||
builder.addHttpListener(realPort, "0.0.0.0");
|
builder.addHttpListener(port, "0.0.0.0");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
configureSsl(port, builder);
|
||||||
|
}
|
||||||
|
for (UndertowBuilderCustomizer customizer : this.undertowBuilderCustomizers) {
|
||||||
|
customizer.customize(builder);
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureSsl(int port, Builder builder) {
|
||||||
try {
|
try {
|
||||||
Ssl ssl = getSsl();
|
Ssl ssl = getSsl();
|
||||||
SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol());
|
SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol());
|
||||||
sslContext.init(getKeyManagers(), getTrustManagers(), null);
|
sslContext.init(getKeyManagers(), getTrustManagers(), null);
|
||||||
builder.addHttpsListener(realPort, "0.0.0.0", sslContext);
|
builder.addHttpsListener(port, "0.0.0.0", sslContext);
|
||||||
if (ssl.getClientAuth() == ClientAuth.NEED) {
|
if (ssl.getClientAuth() == ClientAuth.NEED) {
|
||||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUIRED);
|
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUIRED);
|
||||||
}
|
}
|
||||||
|
@ -212,17 +231,13 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, NOT_REQUESTED);
|
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, NOT_REQUESTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e) {
|
catch (NoSuchAlgorithmException ex) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
catch (KeyManagementException e) {
|
catch (KeyManagementException ex) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
|
||||||
realPort, realPort > 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private KeyManager[] getKeyManagers() {
|
private KeyManager[] getKeyManagers() {
|
||||||
try {
|
try {
|
||||||
|
@ -244,8 +259,8 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
keyManagerFactory.init(keyStore, keyPassword);
|
keyManagerFactory.init(keyStore, keyPassword);
|
||||||
return keyManagerFactory.getKeyManagers();
|
return keyManagerFactory.getKeyManagers();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception ex) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,10 +286,100 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
trustManagerFactory.init(trustedKeyStore);
|
trustManagerFactory.init(trustedKeyStore);
|
||||||
return trustManagerFactory.getTrustManagers();
|
return trustManagerFactory.getTrustManagers();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception ex) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DeploymentManager createDeploymentManager(
|
||||||
|
ServletContextInitializer... initializers) {
|
||||||
|
DeploymentInfo servletBuilder = deployment();
|
||||||
|
|
||||||
|
servletBuilder.addListener(new ListenerInfo(
|
||||||
|
UndertowSpringServletContextListener.class,
|
||||||
|
new UndertowSpringServletContextListenerFactory(
|
||||||
|
new UndertowSpringServletContextListener(
|
||||||
|
mergeInitializers(initializers)))));
|
||||||
|
|
||||||
|
if (this.resourceLoader != null) {
|
||||||
|
servletBuilder.setClassLoader(this.resourceLoader.getClassLoader());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
servletBuilder.setClassLoader(getClass().getClassLoader());
|
||||||
|
}
|
||||||
|
servletBuilder.setContextPath(getContextPath());
|
||||||
|
servletBuilder.setDeploymentName("spring-boot");
|
||||||
|
if (isRegisterDefaultServlet()) {
|
||||||
|
servletBuilder.addServlet(servlet("default", DefaultServlet.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
configureErrorPages(servletBuilder);
|
||||||
|
servletBuilder.setServletStackTraces(ServletStackTraces.NONE);
|
||||||
|
|
||||||
|
File root = getValidDocumentRoot();
|
||||||
|
if (root != null && root.isDirectory()) {
|
||||||
|
servletBuilder.setResourceManager(new FileResourceManager(root, 0));
|
||||||
|
}
|
||||||
|
else if (root != null && root.isFile()) {
|
||||||
|
servletBuilder.setResourceManager(new JarResourcemanager(root));
|
||||||
|
}
|
||||||
|
else if (this.resourceLoader != null) {
|
||||||
|
servletBuilder.setResourceManager(new ClassPathResourceManager(
|
||||||
|
this.resourceLoader.getClassLoader(), ""));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
servletBuilder.setResourceManager(new ClassPathResourceManager(getClass()
|
||||||
|
.getClassLoader(), ""));
|
||||||
|
}
|
||||||
|
for (Mapping mimeMapping : getMimeMappings()) {
|
||||||
|
servletBuilder.addMimeMapping(new MimeMapping(mimeMapping.getExtension(),
|
||||||
|
mimeMapping.getMimeType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
|
||||||
|
|
||||||
|
manager.deploy();
|
||||||
|
|
||||||
|
manager.getDeployment().getSessionManager()
|
||||||
|
.setDefaultSessionTimeout(getSessionTimeout());
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureErrorPages(DeploymentInfo servletBuilder) {
|
||||||
|
for (ErrorPage errorPage : getErrorPages()) {
|
||||||
|
if (errorPage.getStatus() != null) {
|
||||||
|
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||||
|
errorPage.getPath(), errorPage.getStatusCode());
|
||||||
|
servletBuilder.addErrorPage(undertowErrorpage);
|
||||||
|
}
|
||||||
|
else if (errorPage.getException() != null) {
|
||||||
|
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||||
|
errorPage.getPath(), errorPage.getException());
|
||||||
|
servletBuilder.addErrorPage(undertowErrorpage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||||
|
errorPage.getPath());
|
||||||
|
servletBuilder.addErrorPage(undertowErrorpage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method called to create the {@link UndertowEmbeddedServletContainer}.
|
||||||
|
* Subclasses can override this method to return a different
|
||||||
|
* {@link UndertowEmbeddedServletContainer} 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 UndertowEmbeddedServletContainer} instance
|
||||||
|
*/
|
||||||
|
protected UndertowEmbeddedServletContainer getUndertowEmbeddedServletContainer(
|
||||||
|
Builder builder, DeploymentManager manager, int port) {
|
||||||
|
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
||||||
|
port, port >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -302,6 +407,12 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
this.directBuffers = directBuffers;
|
this.directBuffers = directBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRegisterJspServlet(boolean registerJspServlet) {
|
||||||
|
Assert.isTrue(!registerJspServlet, "Undertow does not support JSPs");
|
||||||
|
super.setRegisterJspServlet(registerJspServlet);
|
||||||
|
}
|
||||||
|
|
||||||
private static class JarResourcemanager implements ResourceManager {
|
private static class JarResourcemanager implements ResourceManager {
|
||||||
private final String jarPath;
|
private final String jarPath;
|
||||||
|
|
||||||
|
@ -320,7 +431,7 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Resource getResource(String path) throws IOException {
|
public Resource getResource(String path) throws IOException {
|
||||||
URL url = new URL("jar:file:" + jarPath + "!" + path);
|
URL url = new URL("jar:file:" + this.jarPath + "!" + path);
|
||||||
URLResource resource = new URLResource(url, url.openConnection(), path);
|
URLResource resource = new URLResource(url, url.openConnection(), path);
|
||||||
if (resource.getContentLength() < 0) {
|
if (resource.getContentLength() < 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -361,7 +472,7 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
public InstanceHandle<UndertowSpringServletContextListener> createInstance()
|
public InstanceHandle<UndertowSpringServletContextListener> createInstance()
|
||||||
throws InstantiationException {
|
throws InstantiationException {
|
||||||
return new ImmediateInstanceHandle<UndertowSpringServletContextListener>(
|
return new ImmediateInstanceHandle<UndertowSpringServletContextListener>(
|
||||||
listener);
|
this.listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -376,14 +487,14 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
public void contextInitialized(ServletContextEvent event) {
|
||||||
try {
|
try {
|
||||||
for (ServletContextInitializer initializer : initializers) {
|
for (ServletContextInitializer initializer : this.initializers) {
|
||||||
initializer.onStartup(sce.getServletContext());
|
initializer.onStartup(event.getServletContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ServletException e) {
|
catch (ServletException ex) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for Undertow {@link org.springframework.boot.context.embedded.EmbeddedServletContainer EmbeddedServletContainers}.
|
||||||
|
*
|
||||||
|
* @see org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.embedded.undertow;
|
||||||
|
|
|
@ -49,6 +49,7 @@ import static org.junit.Assert.assertThat;
|
||||||
* {@link EmbeddedServletContainer}s running Spring MVC.
|
* {@link EmbeddedServletContainer}s running Spring MVC.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Ivan Sopov
|
||||||
*/
|
*/
|
||||||
public class EmbeddedServletContainerMvcIntegrationTests {
|
public class EmbeddedServletContainerMvcIntegrationTests {
|
||||||
|
|
||||||
|
@ -84,9 +85,6 @@ public class EmbeddedServletContainerMvcIntegrationTests {
|
||||||
doTest(this.context, "/hello");
|
doTest(this.context, "/hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void advancedConfig() throws Exception {
|
public void advancedConfig() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||||
|
|
|
@ -1,34 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.context.embedded.undertow;
|
package org.springframework.boot.context.embedded.undertow;
|
||||||
|
|
||||||
|
import io.undertow.Undertow.Builder;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.context.embedded.*;
|
import org.mockito.InOrder;
|
||||||
|
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||||
|
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
|
||||||
|
import org.springframework.boot.context.embedded.ErrorPage;
|
||||||
|
import org.springframework.boot.context.embedded.ExampleServlet;
|
||||||
|
import org.springframework.boot.context.embedded.ServletRegistrationBean;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
|
import static org.mockito.Mockito.inOrder;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory} and
|
* Tests for {@link UndertowEmbeddedServletContainerFactory} and
|
||||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainer}.
|
* {@link UndertowEmbeddedServletContainer} .
|
||||||
*
|
*
|
||||||
* @author Ivan Sopov
|
* @author Ivan Sopov
|
||||||
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
public class UndertowEmbeddedServletContainerFactoryTests extends AbstractEmbeddedServletContainerFactoryTests
|
public class UndertowEmbeddedServletContainerFactoryTests extends
|
||||||
{
|
AbstractEmbeddedServletContainerFactoryTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected UndertowEmbeddedServletContainerFactory getFactory()
|
protected UndertowEmbeddedServletContainerFactory getFactory() {
|
||||||
{
|
return new UndertowEmbeddedServletContainerFactory(0);
|
||||||
return new UndertowEmbeddedServletContainerFactory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void errorPage404() throws Exception {
|
public void errorPage404() throws Exception {
|
||||||
AbstractEmbeddedServletContainerFactory factory = getFactory();
|
AbstractEmbeddedServletContainerFactory factory = getFactory();
|
||||||
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello"));
|
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello"));
|
||||||
this.container = factory.getEmbeddedServletContainer(new ServletRegistrationBean(new ExampleServlet(), "/hello"));
|
this.container = factory.getEmbeddedServletContainer(new ServletRegistrationBean(
|
||||||
|
new ExampleServlet(), "/hello"));
|
||||||
this.container.start();
|
this.container.start();
|
||||||
assertThat(getResponse("http://localhost:8080/hello"), equalTo("Hello World"));
|
assertThat(getResponse(getLocalUrl("/hello")), equalTo("Hello World"));
|
||||||
assertThat(getResponse("http://localhost:8080/not-found"), equalTo("Hello World"));
|
assertThat(getResponse(getLocalUrl("/not-found")), equalTo("Hello World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNullUndertowBuilderCustomizersThrows() {
|
||||||
|
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("undertowBuilderCustomizers must not be null");
|
||||||
|
factory.setUndertowBuilderCustomizers(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addNullContextCustomizersThrows() {
|
||||||
|
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("undertowBuilderCustomizers must not be null");
|
||||||
|
factory.addUndertowBuilderCustomizers((UndertowBuilderCustomizer[]) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builderCustomizers() throws Exception {
|
||||||
|
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||||
|
UndertowBuilderCustomizer[] customizers = new UndertowBuilderCustomizer[4];
|
||||||
|
for (int i = 0; i < customizers.length; i++) {
|
||||||
|
customizers[i] = mock(UndertowBuilderCustomizer.class);
|
||||||
|
}
|
||||||
|
factory.setUndertowBuilderCustomizers(Arrays.asList(customizers[0],
|
||||||
|
customizers[1]));
|
||||||
|
factory.addUndertowBuilderCustomizers(customizers[2], customizers[3]);
|
||||||
|
this.container = factory.getEmbeddedServletContainer();
|
||||||
|
InOrder ordered = inOrder((Object[]) customizers);
|
||||||
|
for (UndertowBuilderCustomizer customizer : customizers) {
|
||||||
|
ordered.verify(customizer).customize((Builder) anyObject());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue