001// Copyright 2011, 2013 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 015package org.apache.tapestry5.test; 016 017import org.apache.catalina.Context; 018import org.apache.catalina.Engine; 019import org.apache.catalina.Host; 020import org.apache.catalina.Wrapper; 021import org.apache.catalina.connector.Connector; 022import org.apache.catalina.loader.WebappLoader; 023import org.apache.catalina.servlets.DefaultServlet; 024import org.apache.catalina.startup.Embedded; 025 026import java.io.File; 027 028/** 029 * Launches an instance of Tomcat 6. 030 * 031 * @since 5.3 032 */ 033public 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(TapestryRunnerConstants.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 @Override 108 public void stop() 109 { 110 System.out.printf("Stopping Tomcat instance on port %d/%d\n", port, sslPort); 111 112 try 113 { 114 // Stop immediately and not gracefully. 115 tomcatServer.stop(); 116 } 117 catch (Exception ex) 118 { 119 throw new RuntimeException("Error stopping Tomcat6 instance: " + ex.toString(), ex); 120 } 121 122 System.out.println("Tomcat instance has stopped."); 123 } 124 125 @Override 126 public String toString() 127 { 128 return description; 129 } 130 131 /** 132 * Needed inside Maven multi-projects to expand a path relative to the module to a complete 133 * path. If the path already is absolute and points to an existing directory, it will be used 134 * unchanged. 135 * 136 * @param moduleLocalPath 137 * @return expanded path 138 * @see TapestryRunnerConstants#MODULE_BASE_DIR 139 */ 140 protected String expand(String moduleLocalPath) 141 { 142 File path = new File(moduleLocalPath); 143 144 // Don't expand if the path provided already exists. 145 if (path.isAbsolute() && path.isDirectory()) 146 return moduleLocalPath; 147 148 return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath(); 149 } 150 151}