package au.edu.educationau.opensource.devsupport; import java.util.ArrayList; import java.util.List; import org.mortbay.jetty.Handler; import org.mortbay.jetty.Server; import org.mortbay.jetty.bio.SocketConnector; import org.mortbay.jetty.handler.DefaultHandler; import org.mortbay.jetty.handler.HandlerCollection; import org.mortbay.jetty.security.SslSocketConnector; import org.mortbay.jetty.webapp.WebAppContext; import au.edu.educationau.opensource.spring20.EnvironmentPropertyConfigurer; /** *

Use this in development to run a Jetty instance which will use the classes + resources straight out of the source tree (ie. no need to package + redeploy * etc. each time a file is changed). The expanded web application will be run from the directory src/main/webapp relative to the project root.

* *

It will default to running on port 80, but this can be altered using the test.webserver.port system property.

* *

Turn SSL on using the test.webserver.usessl system property (true/false), and set the SSL port with the test.webserver.sslport * system property (default is 443). If you use SSL you will need to create a key. The best docs for that are * http://docs.codehaus.org/display/JETTY/How+to+configure+SSL#HowtoconfigureSSL-step4 * but the easiest way is

* keytool -keystore keystore -alias jetty -genkey -keyalg RSA

* The key should be deployed to src/test/resources/keystore relative to the project root. Passwords for the keystore password, * key and truststore all default to password but may be specified using the * test.webserver.ssl.storepassword, test.webserver.ssl.keypassword and test.webserver.ssl.trustpassword system properties. *

* *

Note that the the web application will be loaded before the webserver ports are set. This means that code in the web application has a * chance to set the relevent system properties. This enables the use of {@link EnvironmentPropertyConfigurer} for configuration. * */ public class TestWebServer { public static void main(String[] args) throws Exception { Server server = new Server(); // don't specify the port here WebAppContext firstWebappContext = new WebAppContext(); firstWebappContext.setContextPath(System.getProperty("test.webserver.webapp.context") != null ? System.getProperty("test.webserver.webapp.context") : "/"); firstWebappContext.setWar(System.getProperty("test.webserver.webapp.war") != null ? System.getProperty("test.webserver.webapp.war") : "src/main/webapp"); List handlerList = new ArrayList(); // add extra webapps if configured by properties "test.webserver.webapp2.context" etc. for (int i = 2; i < 100; i++) { if (System.getProperty("test.webserver.webapp" + i + ".context") != null) { WebAppContext extraWebappContext = new WebAppContext(); extraWebappContext.setContextPath(System.getProperty("test.webserver.webapp" + i + ".context")); if (System.getProperty("test.webserver.webapp" + i + ".war") == null) { throw new RuntimeException("No war folder specified for webapp " + i); } extraWebappContext.setWar(System.getProperty("test.webserver.webapp" + i + ".war")); handlerList.add(extraWebappContext); } } // NOTE: the reason the "first" context is in the list after the extra ones, is because it's usually "/" context - // if it was first in the list, Jetty won't let other contexts register (i.e. "/" will swallow all requests) handlerList.add(firstWebappContext); handlerList.add(new DefaultHandler()); HandlerCollection handlerCollection = new HandlerCollection(); handlerCollection.setHandlers(handlerList.toArray(new Handler[0])); server.setHandler(handlerCollection); // Start the server before adding the connectors // This allows the web-app to load, so if system properties are set inside the application they will be available server.start(); int port = 80; if (System.getProperty("test.webserver.port") != null && Integer.getInteger("test.webserver.port").intValue() > 0) { port = Integer.getInteger("test.webserver.port").intValue(); } SocketConnector connector = new SocketConnector(); connector.setPort(port); server.addConnector(connector); connector.start(); int sslport = 443; boolean usingHttps = false; if (Boolean.getBoolean("test.webserver.usessl")) { if (System.getProperty("test.webserver.sslport") != null && Integer.getInteger("test.webserver.sslport").intValue() > 0) { sslport = Integer.getInteger("test.webserver.sslport").intValue(); } // Docs on how to generate a keystore are available from http://docs.codehaus.org/display/JETTY/How+to+configure+SSL#HowtoconfigureSSL-step4 // The easiest way is to use the JDK keytool: // keytool -keystore keystore -alias jetty -genkey -keyalg RSA // SslSocketConnector sslConnector = new SslSocketConnector(); sslConnector.setPort(sslport); sslConnector.setKeystore("src/test/resources/keystore"); sslConnector.setPassword(System.getProperty("test.webserver.ssl.storepassword", "password")); sslConnector.setKeyPassword(System.getProperty("test.webserver.ssl.keypassword", "password")); sslConnector.setTruststore("src/test/resources/keystore"); sslConnector.setTrustPassword(System.getProperty("test.webserver.ssl.trustpassword", "password")); server.addConnector(sslConnector); sslConnector.start(); usingHttps = true; } System.out.println(TestWebServer.class.getName() + " started on port " + port); if (usingHttps) { System.out.println(TestWebServer.class.getName() + " running https on port " + sslport); } else { System.out.println(TestWebServer.class.getName() + " https disabled"); } } }