001 // Copyright 2011 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry5.test; 016 017 import org.apache.catalina.Context; 018 import org.apache.catalina.Engine; 019 import org.apache.catalina.Host; 020 import org.apache.catalina.Wrapper; 021 import org.apache.catalina.connector.Connector; 022 import org.apache.catalina.loader.WebappLoader; 023 import org.apache.catalina.servlets.DefaultServlet; 024 import org.apache.catalina.startup.Embedded; 025 026 import java.io.File; 027 028 /** 029 * Launches an instance of Tomcat 6. 030 * 031 * @since 5.3 032 */ 033 public class Tomcat6Runner implements ServletContainerRunner 034 { 035 private final String description; 036 private final int port; 037 private final int sslPort; 038 private Embedded tomcatServer; 039 040 public Tomcat6Runner(String webappFolder, String contextPath, int port, int sslPort) throws Exception 041 { 042 this.port = port; 043 044 this.sslPort = sslPort; 045 046 final String expandedPath = expand(webappFolder); 047 048 description = String.format("<Tomcat6Runner:%s:%s/%s (%s)", contextPath, port, sslPort, expandedPath); 049 050 tomcatServer = new Embedded(); 051 052 // Tomcat creates a folder, try to put it in an OS agnostic tmp dir 053 String tmpDir = System.getProperty("java.io.tmpdir"); 054 String fileSeparator = System.getProperty("file.separator"); 055 if (!tmpDir.endsWith(fileSeparator)) 056 tmpDir = tmpDir + fileSeparator; 057 tomcatServer.setCatalinaHome(tmpDir + "tomcat"); 058 059 final Engine engine = tomcatServer.createEngine(); 060 engine.setDefaultHost("localhost"); 061 062 final Host host = tomcatServer.createHost("localhost", expandedPath); 063 engine.addChild(host); 064 065 final Context context = tomcatServer.createContext(contextPath, expandedPath); 066 067 // Without a servlet the filter will not get run. 068 final Wrapper wrapper = context.createWrapper(); 069 final String name = "DefaultServlet"; 070 wrapper.setName(name); 071 wrapper.setServletClass(DefaultServlet.class.getName()); 072 context.addChild(wrapper); 073 context.addServletMapping("/", name); 074 075 File contextConfigFile = new File(webappFolder, "META-INF/context.xml"); 076 077 if (contextConfigFile.exists()) 078 context.setConfigFile(contextConfigFile.getAbsolutePath()); 079 080 context.setLoader(new WebappLoader(this.getClass().getClassLoader())); 081 082 host.addChild(context); 083 084 tomcatServer.addEngine(engine); 085 086 Connector http = tomcatServer.createConnector("localhost", port, false); 087 http.setAllowTrace(true); 088 tomcatServer.addConnector(http); 089 090 // SSL support 091 final File keystoreFile = new File(TapestryTestConstants.MODULE_BASE_DIR, "src/test/conf/keystore"); 092 093 if (keystoreFile.exists()) 094 { 095 final Connector https = tomcatServer.createConnector("localhost", sslPort, true); 096 https.setProperty("keystore", keystoreFile.getPath()); 097 https.setProperty("keypass", "tapestry"); 098 tomcatServer.addConnector(https); 099 } 100 101 tomcatServer.start(); 102 } 103 104 /** 105 * Immediately shuts down the server instance. 106 */ 107 public void stop() 108 { 109 System.out.printf("Stopping Tomcat instance on port %d/%d\n", port, sslPort); 110 111 try 112 { 113 // Stop immediately and not gracefully. 114 tomcatServer.stop(); 115 } 116 catch (Exception ex) 117 { 118 throw new RuntimeException("Error stopping Tomcat6 instance: " + ex.toString(), ex); 119 } 120 121 System.out.println("Tomcat instance has stopped."); 122 } 123 124 @Override 125 public String toString() 126 { 127 return description; 128 } 129 130 /** 131 * Needed inside Maven multi-projects to expand a path relative to the module to a complete 132 * path. If the path already is absolute and points to an existing directory, it will be used 133 * unchanged. 134 * 135 * @param moduleLocalPath 136 * @return expanded path 137 * @see TapestryTestConstants#MODULE_BASE_DIR 138 */ 139 protected String expand(String moduleLocalPath) 140 { 141 File path = new File(moduleLocalPath); 142 143 // Don't expand if the path provided already exists. 144 if (path.isAbsolute() && path.isDirectory()) 145 return moduleLocalPath; 146 147 return new File(TapestryTestConstants.MODULE_BASE_DIR, moduleLocalPath).getPath(); 148 } 149 150 }