From a641f0c72ab18d77ecde069a78bfab3d1bbbb03d Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 18 Nov 2014 15:40:24 -0800 Subject: [PATCH] Polish --- .../actuator/log4j/SampleController.java | 1 + .../actuator/log4j2/SampleController.java | 1 + .../sample/data/jpa/web/SampleController.java | 1 + .../sample/jetty/web/SampleController.java | 1 + .../sample/jetty/web/SampleController.java | 1 + .../sample/jetty/web/SampleController.java | 1 + .../sample/jetty/web/SampleController.java | 1 + .../sample/tomcat/web/SampleController.java | 1 + .../sample/undertow/web/SampleController.java | 1 + .../sample/undertow/web/SampleController.java | 1 + .../UndertowEmbeddedServletContainer.java | 40 ++-- ...dertowEmbeddedServletContainerFactory.java | 203 ++++++++---------- ...wEmbeddedServletContainerFactoryTests.java | 6 + 13 files changed, 125 insertions(+), 134 deletions(-) diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j/src/main/java/sample/actuator/log4j/SampleController.java b/spring-boot-samples/spring-boot-sample-actuator-log4j/src/main/java/sample/actuator/log4j/SampleController.java index 5e9c0a9620..43ea074981 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j/src/main/java/sample/actuator/log4j/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j/src/main/java/sample/actuator/log4j/SampleController.java @@ -42,4 +42,5 @@ public class SampleController { public String foo() { throw new IllegalArgumentException("Server error"); } + } diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java index dfdde4d642..4cee532cc4 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java @@ -42,4 +42,5 @@ public class SampleController { public String foo() { throw new IllegalArgumentException("Server error"); } + } diff --git a/spring-boot-samples/spring-boot-sample-data-jpa/src/main/java/sample/data/jpa/web/SampleController.java b/spring-boot-samples/spring-boot-sample-data-jpa/src/main/java/sample/data/jpa/web/SampleController.java index d6f8687f6d..50f1fccc06 100644 --- a/spring-boot-samples/spring-boot-sample-data-jpa/src/main/java/sample/data/jpa/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-data-jpa/src/main/java/sample/data/jpa/web/SampleController.java @@ -36,4 +36,5 @@ public class SampleController { public String helloWorld() { return this.cityService.getCity("Bath", "UK").getName(); } + } diff --git a/spring-boot-samples/spring-boot-sample-jetty-ssl/src/main/java/sample/jetty/web/SampleController.java b/spring-boot-samples/spring-boot-sample-jetty-ssl/src/main/java/sample/jetty/web/SampleController.java index d3eb1f70a9..6d8062d2b5 100644 --- a/spring-boot-samples/spring-boot-sample-jetty-ssl/src/main/java/sample/jetty/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-jetty-ssl/src/main/java/sample/jetty/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot-samples/spring-boot-sample-jetty/src/main/java/sample/jetty/web/SampleController.java b/spring-boot-samples/spring-boot-sample-jetty/src/main/java/sample/jetty/web/SampleController.java index d3eb1f70a9..6d8062d2b5 100644 --- a/spring-boot-samples/spring-boot-sample-jetty/src/main/java/sample/jetty/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-jetty/src/main/java/sample/jetty/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot-samples/spring-boot-sample-jetty8-ssl/src/main/java/sample/jetty/web/SampleController.java b/spring-boot-samples/spring-boot-sample-jetty8-ssl/src/main/java/sample/jetty/web/SampleController.java index d3eb1f70a9..6d8062d2b5 100644 --- a/spring-boot-samples/spring-boot-sample-jetty8-ssl/src/main/java/sample/jetty/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-jetty8-ssl/src/main/java/sample/jetty/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot-samples/spring-boot-sample-jetty8/src/main/java/sample/jetty/web/SampleController.java b/spring-boot-samples/spring-boot-sample-jetty8/src/main/java/sample/jetty/web/SampleController.java index d3eb1f70a9..6d8062d2b5 100644 --- a/spring-boot-samples/spring-boot-sample-jetty8/src/main/java/sample/jetty/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-jetty8/src/main/java/sample/jetty/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors/src/main/java/sample/tomcat/web/SampleController.java b/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors/src/main/java/sample/tomcat/web/SampleController.java index 1af3656bb2..0636bc2f76 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors/src/main/java/sample/tomcat/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors/src/main/java/sample/tomcat/web/SampleController.java @@ -26,4 +26,5 @@ public class SampleController { public String helloWorld() { return "hello"; } + } diff --git a/spring-boot-samples/spring-boot-sample-undertow-ssl/src/main/java/sample/undertow/web/SampleController.java b/spring-boot-samples/spring-boot-sample-undertow-ssl/src/main/java/sample/undertow/web/SampleController.java index 3084fbd6e3..c16bb6dabd 100644 --- a/spring-boot-samples/spring-boot-sample-undertow-ssl/src/main/java/sample/undertow/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-undertow-ssl/src/main/java/sample/undertow/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot-samples/spring-boot-sample-undertow/src/main/java/sample/undertow/web/SampleController.java b/spring-boot-samples/spring-boot-sample-undertow/src/main/java/sample/undertow/web/SampleController.java index 3084fbd6e3..c16bb6dabd 100644 --- a/spring-boot-samples/spring-boot-sample-undertow/src/main/java/sample/undertow/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-undertow/src/main/java/sample/undertow/web/SampleController.java @@ -34,4 +34,5 @@ public class SampleController { public String helloWorld() { return this.helloWorldService.getHelloMessage(); } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java index 7e7e8cee22..3c0c1a32e3 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java @@ -20,7 +20,6 @@ import io.undertow.Handlers; import io.undertow.Undertow; import io.undertow.Undertow.Builder; import io.undertow.server.HttpHandler; -import io.undertow.server.handlers.PathHandler; import io.undertow.servlet.api.DeploymentManager; import javax.servlet.ServletException; @@ -70,27 +69,32 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine return; } if (this.undertow == null) { - try { - HttpHandler servletHandler = this.manager.start(); - if (StringUtils.isEmpty(this.contextPath)) { - this.builder.setHandler(servletHandler); - } - else { - PathHandler pathHandler = Handlers.path().addPrefixPath( - this.contextPath, servletHandler); - this.builder.setHandler(pathHandler); - } - this.undertow = this.builder.build(); - } - catch (ServletException ex) { - throw new EmbeddedServletContainerException( - "Unable to start embdedded Undertow", ex); - } + this.undertow = createUndertowServer(); } this.undertow.start(); this.started = true; } + private Undertow createUndertowServer() { + try { + HttpHandler servletHandler = this.manager.start(); + this.builder.setHandler(getContextHandler(servletHandler)); + return this.builder.build(); + } + catch (ServletException ex) { + throw new EmbeddedServletContainerException( + "Unable to start embdedded Undertow", ex); + } + } + + private HttpHandler getContextHandler(HttpHandler servletHandler) { + if (StringUtils.isEmpty(this.contextPath)) { + return servletHandler; + } + return Handlers.path().addPrefixPath(this.contextPath, servletHandler); + + } + @Override public synchronized void stop() throws EmbeddedServletContainerException { if (this.started) { @@ -104,4 +108,4 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine return this.port; } -} \ No newline at end of file +} diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java index 6231994a01..e60f8b7f83 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java @@ -25,15 +25,15 @@ 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.DeploymentInfo; import io.undertow.servlet.api.DeploymentManager; -import io.undertow.servlet.api.InstanceFactory; -import io.undertow.servlet.api.InstanceHandle; import io.undertow.servlet.api.ListenerInfo; import io.undertow.servlet.api.MimeMapping; import io.undertow.servlet.api.ServletStackTraces; import io.undertow.servlet.handlers.DefaultServlet; -import io.undertow.servlet.util.ImmediateInstanceHandle; +import io.undertow.servlet.util.ImmediateInstanceFactory; import java.io.File; import java.io.IOException; @@ -68,14 +68,8 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; import org.springframework.util.ResourceUtils; 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; +import org.xnio.Options; +import org.xnio.SslClientAuthMode; /** * {@link EmbeddedServletContainerFactory} that can be used to create @@ -173,14 +167,11 @@ public class UndertowEmbeddedServletContainerFactory extends public EmbeddedServletContainer getEmbeddedServletContainer( ServletContextInitializer... initializers) { DeploymentManager manager = createDeploymentManager(initializers); - int port = getPort(); if (port == 0) { port = SocketUtils.findAvailableTcpPort(40000); } - Builder builder = createBuilder(port); - return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(), port, port >= 0); } @@ -202,7 +193,6 @@ public class UndertowEmbeddedServletContainerFactory extends if (this.directBuffers != null) { builder.setDirectBuffers(this.directBuffers); } - if (getSsl() == null) { builder.addHttpListener(port, "0.0.0.0"); } @@ -221,28 +211,30 @@ public class UndertowEmbeddedServletContainerFactory extends SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol()); sslContext.init(getKeyManagers(), getTrustManagers(), null); builder.addHttpsListener(port, "0.0.0.0", sslContext); - if (ssl.getClientAuth() == ClientAuth.NEED) { - builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUIRED); - } - else if (ssl.getClientAuth() == ClientAuth.WANT) { - builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUESTED); - } - else { - builder.setSocketOption(SSL_CLIENT_AUTH_MODE, NOT_REQUESTED); - } + builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, + getSslClientAuthMode(ssl)); } catch (NoSuchAlgorithmException ex) { - throw new RuntimeException(ex); + throw new IllegalStateException(ex); } catch (KeyManagementException ex) { - throw new RuntimeException(ex); + throw new IllegalStateException(ex); } } + private SslClientAuthMode getSslClientAuthMode(Ssl ssl) { + if (ssl.getClientAuth() == ClientAuth.NEED) { + return SslClientAuthMode.REQUIRED; + } + if (ssl.getClientAuth() == ClientAuth.WANT) { + return SslClientAuthMode.REQUESTED; + } + return SslClientAuthMode.NOT_REQUESTED; + } + private KeyManager[] getKeyManagers() { try { Ssl ssl = getSsl(); - String keyStoreType = ssl.getKeyStoreType(); if (keyStoreType == null) { keyStoreType = "JKS"; @@ -260,14 +252,13 @@ public class UndertowEmbeddedServletContainerFactory extends return keyManagerFactory.getKeyManagers(); } catch (Exception ex) { - throw new RuntimeException(ex); + throw new IllegalStateException(ex); } } private TrustManager[] getTrustManagers() { try { Ssl ssl = getSsl(); - String trustStoreType = ssl.getTrustStoreType(); if (trustStoreType == null) { trustStoreType = "JKS"; @@ -280,88 +271,83 @@ public class UndertowEmbeddedServletContainerFactory extends URL url = ResourceUtils.getURL(trustStore); trustedKeyStore.load(url.openStream(), ssl.getTrustStorePassword() .toCharArray()); - TrustManagerFactory trustManagerFactory = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustedKeyStore); return trustManagerFactory.getTrustManagers(); } catch (Exception ex) { - throw new RuntimeException(ex); + throw new IllegalStateException(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"); + DeploymentInfo deployment = Servlets.deployment(); + ServletContextInitializer[] mergeInitializers = mergeInitializers(initializers); + StartupListener startupListener = new StartupListener(mergeInitializers); + deployment.addListener(new ListenerInfo(StartupListener.class, + new ImmediateInstanceFactory(startupListener))); + deployment.setClassLoader(getServletClassLoader()); + deployment.setContextPath(getContextPath()); + deployment.setDeploymentName("spring-boot"); if (isRegisterDefaultServlet()) { - servletBuilder.addServlet(servlet("default", DefaultServlet.class)); + deployment.addServlet(Servlets.servlet("default", DefaultServlet.class)); } + configureErrorPages(deployment); + deployment.setServletStackTraces(ServletStackTraces.NONE); + deployment.setResourceManager(getDocumentRootResourceManager()); + configureMimeMappings(deployment); + DeploymentManager manager = Servlets.defaultContainer().addDeployment(deployment); + manager.deploy(); + SessionManager sessionManager = manager.getDeployment().getSessionManager(); + sessionManager.setDefaultSessionTimeout(getSessionTimeout()); + return manager; + } - configureErrorPages(servletBuilder); - servletBuilder.setServletStackTraces(ServletStackTraces.NONE); + private ClassLoader getServletClassLoader() { + if (this.resourceLoader != null) { + return this.resourceLoader.getClassLoader(); + } + return getClass().getClassLoader(); + } + private ResourceManager getDocumentRootResourceManager() { File root = getValidDocumentRoot(); if (root != null && root.isDirectory()) { - servletBuilder.setResourceManager(new FileResourceManager(root, 0)); + return new FileResourceManager(root, 0); } - else if (root != null && root.isFile()) { - servletBuilder.setResourceManager(new JarResourcemanager(root)); + if (root != null && root.isFile()) { + return new JarResourcemanager(root); } - else if (this.resourceLoader != null) { - servletBuilder.setResourceManager(new ClassPathResourceManager( - this.resourceLoader.getClassLoader(), "")); + if (this.resourceLoader != null) { + return 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; + return new ClassPathResourceManager(getClass().getClassLoader(), ""); } 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); - } + servletBuilder.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 servletBuilder) { + for (Mapping mimeMapping : getMimeMappings()) { + servletBuilder.addMimeMapping(new MimeMapping(mimeMapping.getExtension(), + mimeMapping.getMimeType())); } } @@ -370,7 +356,6 @@ public class UndertowEmbeddedServletContainerFactory extends * 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 @@ -413,7 +398,11 @@ public class UndertowEmbeddedServletContainerFactory extends super.setRegisterJspServlet(registerJspServlet); } + /** + * Undertow {@link ResourceManager} for JAR resources. + */ private static class JarResourcemanager implements ResourceManager { + private final String jarPath; public JarResourcemanager(File jarFile) { @@ -424,11 +413,6 @@ public class UndertowEmbeddedServletContainerFactory extends this.jarPath = jarPath; } - @Override - public void close() throws IOException { - // no code - } - @Override public Resource getResource(String path) throws IOException { URL url = new URL("jar:file:" + this.jarPath + "!" + path); @@ -453,36 +437,23 @@ public class UndertowEmbeddedServletContainerFactory extends @Override public void removeResourceChangeListener(ResourceChangeListener listener) { throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); - - } - - } - - private static class UndertowSpringServletContextListenerFactory implements - InstanceFactory { - - private final UndertowSpringServletContextListener listener; - - public UndertowSpringServletContextListenerFactory( - UndertowSpringServletContextListener listener) { - this.listener = listener; } @Override - public InstanceHandle createInstance() - throws InstantiationException { - return new ImmediateInstanceHandle( - this.listener); + public void close() throws IOException { } } - private static class UndertowSpringServletContextListener implements - ServletContextListener { + /** + * {@link ServletContextListener} to trigger + * {@link ServletContextInitializer#onStartup(javax.servlet.ServletContext)}. + */ + private static class StartupListener implements ServletContextListener { + private final ServletContextInitializer[] initializers; - public UndertowSpringServletContextListener( - ServletContextInitializer... initializers) { + public StartupListener(ServletContextInitializer... initializers) { this.initializers = initializers; } @@ -494,14 +465,14 @@ public class UndertowEmbeddedServletContainerFactory extends } } catch (ServletException ex) { - throw new RuntimeException(ex); + throw new IllegalStateException(ex); } } @Override public void contextDestroyed(ServletContextEvent sce) { - // no code } + } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java index 578cbb5c78..7cccaee257 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java @@ -93,4 +93,10 @@ public class UndertowEmbeddedServletContainerFactoryTests extends ordered.verify(customizer).customize((Builder) anyObject()); } } + + @Test + public void basicSslClasspathKeyStore() throws Exception { + testBasicSllWithKeystore("classpath:test.jks"); + } + }