1 4 package com.tc.test.server.appserver.wasce1x; 5 6 import org.apache.commons.io.FileUtils; 7 import org.codehaus.cargo.container.geronimo.internal.GeronimoUtils; 8 import org.codehaus.cargo.util.log.Logger; 9 10 import com.tc.process.LinkedJavaProcessPollingAgent; 11 import com.tc.process.StreamAppender; 12 import com.tc.test.TestConfigObject; 13 import com.tc.test.server.ServerParameters; 14 import com.tc.test.server.ServerResult; 15 import com.tc.test.server.appserver.AbstractAppServer; 16 import com.tc.test.server.appserver.AppServerParameters; 17 import com.tc.test.server.appserver.AppServerResult; 18 import com.tc.test.server.appserver.cargo.CargoLinkedChildProcess; 19 import com.tc.test.server.util.AppServerUtil; 20 import com.tc.util.Assert; 21 import com.tc.util.concurrent.ThreadUtil; 22 23 import java.io.BufferedReader ; 24 import java.io.File ; 25 import java.io.FileOutputStream ; 26 import java.io.FileReader ; 27 import java.io.FileWriter ; 28 import java.io.IOException ; 29 import java.io.PrintWriter ; 30 import java.util.Arrays ; 31 import java.util.Iterator ; 32 import java.util.LinkedList ; 33 import java.util.List ; 34 import java.util.Map ; 35 import java.util.jar.Attributes ; 36 import java.util.jar.JarFile ; 37 import java.util.jar.Manifest ; 38 import java.util.regex.Pattern ; 39 40 43 public final class Wasce1xAppServer extends AbstractAppServer { 44 45 private static final String JAVA_CMD = System.getProperty("java.home") + File.separator + "bin" 46 + File.separator + "java"; 47 private static final String CONFIG_STORE = "config-store"; 48 private static final String REPOSITORY = "repository"; 49 private static final String VAR = "var"; 50 private static final String BIN = "bin" + File.separator; 51 private static final String SERVER_JAR = BIN + "server.jar"; 52 private static final String SHUTDOWN_JAR = BIN + "shutdown.jar"; 53 private static final String DEPLOYER_JAR = BIN + "deployer.jar"; 54 private static final String CONFIG_DIR = VAR + File.separator + "config"; 55 private static final String CONFIG = "config.xml"; 56 57 private static final String PORT_ATTRIB = ".*<attribute name=\"port\">\\d{4,6}</attribute>.*"; 58 private static final String REDIRECT_PORT_ATTRIB = ".*<attribute name=\"redirectPort\">\\d{4,6}</attribute>.*"; 59 private static final String PORT_PREFIX = "ort\">"; 60 private static final String WEB_PORT_ATTRIB = ".*<gbean name=\"TomcatWebConnector\">.*"; 61 private static final String RMI_PORT_ATTRIB = ".*<gbean name=\"RMIRegistry\">.*"; 62 private static final String RMI_PORT_URL = ".*<attribute name=\"namingProviderUrl\">rmi://0.0.0.0:\\d{4,6}</attribute>.*"; 63 private static final String RMI_PREFIX = "rmi://0.0.0.0:"; 64 private static final String JMX_RMI = ".*<gbean name=\"JMXService\">.*"; 65 private static final String JMX_RMI_PREFIX = "service:jmx:rmi://0.0.0.0:"; 66 67 private static final String BASE_DIR_PROP = "org.apache.geronimo.base.dir"; 68 private static final String TMP_DIR_PROP = "java.io.tmpdir"; 69 private static final String ENDORSED_DIR_PROP = "java.endorsed.dirs"; 70 71 private static final String USERNAME = "system"; 72 private static final String PASSWORD = "manager"; 73 74 private static final long STARTUP_TIMEOUT = 1000 * 240; 75 76 private String className, classpath, endorsedPath, installPath; 77 private int rmiPort; 78 private ConsoleLogger consoleLogger; 79 private static final String LOG_CAT = "WASCE 1.0 STARTUP"; 80 81 public Wasce1xAppServer(Wasce1xAppServerInstallation installation) { 82 super(installation); 83 } 84 85 private File getHome() { 86 return serverInstallDirectory(); 87 } 88 89 public synchronized ServerResult start(ServerParameters rawParams) throws Exception { 90 TestConfigObject config = TestConfigObject.getInstance(); 91 AppServerParameters params = (AppServerParameters) rawParams; 92 int port = AppServerUtil.getPort(); 93 final File instance = createInstance(params); 94 File home = getHome(); 95 installPath = home.getCanonicalPath(); 96 setProperties(params, port, instance); 97 98 interpretJarManifest(new File (home + File.separator + SERVER_JAR)); 99 copyInstanceDirectories(home, instance); 100 parseConfig(new File (instance + File.separator + CONFIG_DIR), port); 101 102 final List cl = new LinkedList (); 103 cl.add(JAVA_CMD); 104 String [] jvmArgs = params.jvmArgs().replaceAll("'", "").split("\\s"); 105 for (int i = 0; i < jvmArgs.length; i++) { 106 if (!("" + jvmArgs[i]).trim().equals("")) cl.add(jvmArgs[i]); 107 } 108 109 cl.add("-D" + ENDORSED_DIR_PROP + "=" + endorsedPath); 110 cl.add("-D" + TMP_DIR_PROP + "=" + instance.getCanonicalPath() + File.separator + VAR + File.separator + "temp"); 111 cl.add("-D" + BASE_DIR_PROP + "=" + instance.getCanonicalPath()); 112 cl.add("-classpath"); 115 cl.add(classpath + File.pathSeparatorChar + config.linkedChildProcessClasspath()); 116 cl.add(CargoLinkedChildProcess.class.getName()); 117 cl.add(className); 118 cl.add(String.valueOf(LinkedJavaProcessPollingAgent.getChildProcessHeartbeatServerPort())); 119 cl.add(instance.toString()); 120 cl.add("--long"); 122 consoleLogger = new ConsoleLogger(params.instanceName()); 123 consoleLogger.info(Arrays.asList(cl.toArray(new String [0])).toString(), LOG_CAT); 124 125 final Logger logger = consoleLogger; 126 final String logFileName = new File (instance.getParent(), instance.getName() + ".log").getAbsolutePath(); 127 128 Thread t = new Thread () { 129 public void run() { 130 FileOutputStream logFile = null; 131 try { 132 logFile = new FileOutputStream (logFileName); 133 Process process = Runtime.getRuntime().exec((String []) cl.toArray(new String [0]), null, instance); 134 StreamAppender appender = new StreamAppender(logFile); 135 appender.writeInput(process.getErrorStream(), process.getInputStream()); 136 if (process.waitFor() != 0) logger.warn("Server exited with exit code other than 0", LOG_CAT); 137 appender.finish(); 138 } catch (Exception e) { 139 logger.warn("Server process failed", LOG_CAT); 140 e.printStackTrace(); 141 } finally { 142 if (logFile != null) { 143 try { 144 logFile.close(); 145 } catch (Exception e) { 146 e.printStackTrace(); 147 } 148 } 149 } 150 } 151 }; 152 t.start(); 153 waitForStartup(port); deployWars(params.wars()); 155 156 return new AppServerResult(port, this); 157 } 158 159 private void waitForStartup(int port) throws Exception { 160 final ClassLoader prevLoader = Thread.currentThread().getContextClassLoader(); 161 final long timeout = System.currentTimeMillis() + STARTUP_TIMEOUT; 162 163 GeronimoUtils utils = new GeronimoUtils(); 164 ClassLoader geronimoLoader = utils.createGeronimoURLClassloader(getHome()); 165 Thread.currentThread().setContextClassLoader(geronimoLoader); 166 try { 167 while (System.currentTimeMillis() < timeout) { 168 boolean started = utils.isGeronimoStarted("localhost", String.valueOf(rmiPort), USERNAME, PASSWORD); 169 if (started) { return; } 170 ThreadUtil.reallySleep(6000); 171 } 172 173 throw new Exception ("WASCE server failed to start in " + STARTUP_TIMEOUT + " millis"); 174 } finally { 175 Thread.currentThread().setContextClassLoader(prevLoader); 176 } 177 } 178 179 private void deployWars(Map wars) throws Exception { 180 Assert.assertNotNull(wars); 181 182 for (Iterator iter = wars.values().iterator(); iter.hasNext();) { 183 List cl = new LinkedList (); 184 cl.add(JAVA_CMD); 185 cl.add("-jar"); 186 cl.add(installPath + File.separator + DEPLOYER_JAR); 187 cl.add("--user"); 188 cl.add(USERNAME); 189 cl.add("--password"); 190 cl.add(PASSWORD); 191 cl.add("--port"); 192 cl.add(String.valueOf(rmiPort)); 193 cl.add("deploy"); 194 cl.add(((File ) iter.next()).toString()); 195 196 consoleLogger.info("Deploying War: " + Arrays.asList(cl.toArray(new String [0])), LOG_CAT); 197 198 Process process = Runtime.getRuntime().exec((String []) cl.toArray(new String [0])); 199 StreamAppender appender = new StreamAppender(System.err); 200 appender.writeInput(process.getErrorStream(), process.getInputStream()); 201 if (process.waitFor() != 0) throw new Exception ("Failed to Deploy WAR: " + rmiPort); 202 appender.finish(); 203 } 204 } 205 206 public synchronized void stop() throws Exception { 207 Assert.assertTrue(rmiPort > 0); 208 StringBuffer cl = new StringBuffer (JAVA_CMD + " -jar "); 209 cl.append(installPath + File.separator + SHUTDOWN_JAR); 210 cl.append(" --user " + USERNAME + " --password " + PASSWORD + " --port " + rmiPort); 211 Process process = Runtime.getRuntime().exec(cl.toString()); 212 StreamAppender appender = new StreamAppender(System.err); 213 appender.writeInput(process.getErrorStream(), process.getInputStream()); 214 if (process.waitFor() != 0) throw new Exception ("Server Shutdown Failed: " + rmiPort); 215 appender.finish(); 216 consoleLogger.info("Server shutdown: " + rmiPort, LOG_CAT); 217 } 218 219 private void copyInstanceDirectories(File home, File instance) throws IOException { 220 String sep = File.separator; 221 FileUtils.copyDirectory(new File (home + sep + CONFIG_STORE), new File (instance + sep + CONFIG_STORE), false); 222 FileUtils.copyDirectory(new File (home + sep + REPOSITORY), new File (instance + sep + REPOSITORY), false); 223 FileUtils.copyDirectory(new File (home + sep + VAR), new File (instance + sep + VAR), false); 224 } 225 226 private void parseConfig(File configDir, int port) throws Exception { 227 File tmpConfig = new File (configDir + File.separator + "tmp_config.xml"); 228 File config = new File (configDir + File.separator + CONFIG); 229 BufferedReader reader = new BufferedReader (new FileReader (config)); 230 PrintWriter writer = new PrintWriter (new FileWriter (tmpConfig)); 231 String line; 232 boolean useServerPort = false; 233 boolean useRMIPort = false; 234 235 while ((line = reader.readLine()) != null) { 236 if (Pattern.matches(RMI_PORT_ATTRIB, line)) { 237 rmiPort = AppServerUtil.getPort(); 238 useRMIPort = true; 239 } 240 if (Pattern.matches(WEB_PORT_ATTRIB, line)) useServerPort = true; 241 if (Pattern.matches(RMI_PORT_URL, line)) { 242 line = line.replaceAll(RMI_PREFIX + "\\d{4,6}", RMI_PREFIX + rmiPort); 243 } 244 if (Pattern.matches(JMX_RMI, line)) { 245 writer.println(line); 246 line = reader.readLine(); 247 String s = "/jndi/rmi://0.0.0.0:"; 248 line = line.replaceAll(JMX_RMI_PREFIX + "\\d{4,6}" + s + "\\d{4,6}", JMX_RMI_PREFIX + AppServerUtil.getPort() 249 + s + rmiPort); 250 } 251 if (Pattern.matches(PORT_ATTRIB, line)) { 252 int newPort = (useServerPort) ? port : AppServerUtil.getPort(); 253 if (useRMIPort) { 254 newPort = rmiPort; 255 useRMIPort = false; 256 } 257 if (useServerPort) useServerPort = false; 258 line = line.replaceAll(PORT_PREFIX + "\\d{4,6}", PORT_PREFIX + newPort); 259 260 } else if (Pattern.matches(REDIRECT_PORT_ATTRIB, line)) { 261 line = line.replaceAll(PORT_PREFIX + "\\d{4,6}", PORT_PREFIX + AppServerUtil.getPort()); 262 } 263 writer.println(line); 264 } 265 reader.close(); 266 writer.flush(); 267 writer.close(); 268 config.delete(); 269 tmpConfig.renameTo(config); 270 } 271 272 private void interpretJarManifest(File jar) throws IOException { 273 String absPath = jar.getCanonicalFile().getParentFile().getParent().replace('\\', '/'); 274 Manifest manifest = new JarFile (jar).getManifest(); 275 Attributes attrib = manifest.getMainAttributes(); 276 String classPathAttrib = attrib.getValue("Class-Path"); 277 classpath = jar + File.pathSeparator; 278 classpath += classPathAttrib.replaceAll("^\\.\\.", absPath).replaceAll("\\s\\.\\.", 279 File.pathSeparatorChar + absPath); 280 endorsedPath = absPath + File.separator + attrib.getValue("Endorsed-Dirs"); 281 className = attrib.getValue("Main-Class"); 282 } 283 } 284 | Popular Tags |