001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.test.server.appserver.cargo;
006:
007: import org.codehaus.cargo.container.ContainerException;
008: import org.codehaus.cargo.container.ContainerType;
009: import org.codehaus.cargo.container.InstalledLocalContainer;
010: import org.codehaus.cargo.container.State;
011: import org.codehaus.cargo.container.configuration.ConfigurationType;
012: import org.codehaus.cargo.container.configuration.LocalConfiguration;
013: import org.codehaus.cargo.container.deployable.WAR;
014: import org.codehaus.cargo.container.property.GeneralPropertySet;
015: import org.codehaus.cargo.container.property.ServletPropertySet;
016: import org.codehaus.cargo.generic.configuration.ConfigurationFactory;
017: import org.codehaus.cargo.generic.configuration.DefaultConfigurationFactory;
018:
019: import com.tc.process.HeartBeatService;
020: import com.tc.process.LinkedJavaProcessPollingAgent;
021: import com.tc.test.server.ServerParameters;
022: import com.tc.test.server.ServerResult;
023: import com.tc.test.server.appserver.AbstractAppServer;
024: import com.tc.test.server.appserver.AppServer;
025: import com.tc.test.server.appserver.AppServerInstallation;
026: import com.tc.test.server.appserver.AppServerParameters;
027: import com.tc.test.server.appserver.AppServerResult;
028: import com.tc.test.server.appserver.cargo.CargoJava.Link;
029: import com.tc.test.server.util.AppServerUtil;
030:
031: import java.io.File;
032: import java.util.Iterator;
033: import java.util.Map;
034: import java.util.Map.Entry;
035:
036: /**
037: * Generic {@link AppServer} implementation which delegates to the Codehaus CARGO package
038: * http://docs.codehaus.org/display/CARGO/Home
039: */
040: public abstract class CargoAppServer extends AbstractAppServer {
041:
042: private InstalledLocalContainer container;
043: private int port;
044: private int linkedPort;
045:
046: // System property used by cargo. This String is referenced in the CARGO patch, therefore it must not be changed
047: public static final String CARGO_JAVA = "cargo_java";
048: public static final String CARGO_JAVA_CLASS = CargoJava.class
049: .getName();
050:
051: static {
052: System.setProperty(CARGO_JAVA, CARGO_JAVA_CLASS);
053: }
054:
055: public CargoAppServer(AppServerInstallation installation) {
056: super (installation);
057: }
058:
059: public final ServerResult start(ServerParameters rawParams)
060: throws Exception {
061: AppServerParameters params = (AppServerParameters) rawParams;
062: port = AppServerUtil.getPort();
063: File instance = createInstance(params);
064: setProperties(params, port, instance);
065:
066: ConfigurationFactory factory = new DefaultConfigurationFactory();
067: LocalConfiguration config = (LocalConfiguration) factory
068: .createConfiguration(cargoServerKey(),
069: ContainerType.INSTALLED,
070: ConfigurationType.STANDALONE, instance
071: .getAbsolutePath());
072: setConfigProperties(config);
073: config.setProperty(ServletPropertySet.PORT, Integer
074: .toString(port));
075: config
076: .setProperty(GeneralPropertySet.JVMARGS, params
077: .jvmArgs());
078: config.setProperty(GeneralPropertySet.LOGGING, "low");
079: addWars(config, params.wars(), params.instanceName());
080:
081: container = container(config);
082: container.setTimeout(8 * 60 * 1000);
083: container.setHome(serverInstallDirectory().getAbsolutePath());
084: container.setLogger(new ConsoleLogger(params.instanceName()));
085: setExtraClasspath(params);
086:
087: linkJavaProcess(instance);
088:
089: container.start();
090:
091: return new AppServerResult(port, this );
092: }
093:
094: public final void stop() {
095: if (container != null) {
096: if (container.getState().equals(State.STARTED)
097: || container.getState().equals(State.STARTING)
098: || container.getState().equals(State.UNKNOWN)) {
099: try {
100: // XXX: clear out the jvmargs so that the VMs spawned for stop() don't try to use DSO
101: // XXX: If you know a better way to do this, go for it
102: String jvmArgs = container.getConfiguration()
103: .getPropertyValue(
104: GeneralPropertySet.JVMARGS);
105: try {
106: container.getConfiguration().setProperty(
107: GeneralPropertySet.JVMARGS, null);
108: container.stop(); // NOTE: stop is not guaranteed to work
109: } finally {
110: container.getConfiguration().setProperty(
111: GeneralPropertySet.JVMARGS, jvmArgs);
112: }
113: } catch (ContainerException e) {
114: throw new RuntimeException(e);
115: }
116: }
117: }
118: }
119:
120: private void addWars(LocalConfiguration config, Map wars,
121: String instanceName) {
122: WAR warapp = null;
123: for (Iterator it = wars.entrySet().iterator(); it.hasNext();) {
124: Map.Entry entry = (Entry) it.next();
125: String context = (String) entry.getKey();
126: File warFile = (File) entry.getValue();
127: System.out.println("WAR: " + warFile);
128: warapp = new WAR(warFile.getPath());
129: warapp.setContext(context);
130: warapp.setLogger(new ConsoleLogger(instanceName));
131: config.addDeployable(warapp);
132: }
133: }
134:
135: /**
136: * Create a linked java process {@link LinkedJavaProcessPollingAgent}
137: *
138: * @throws InterruptedException
139: */
140: private void linkJavaProcess(File instance)
141: throws InterruptedException {
142: linkedPort = HeartBeatService.listenPort();
143: Link.put(new CargoJava.Args(linkedPort, instance));
144: }
145:
146: protected final InstalledLocalContainer container() {
147: return container;
148: }
149:
150: protected abstract String cargoServerKey();
151:
152: protected abstract InstalledLocalContainer container(
153: LocalConfiguration config);
154:
155: protected void setConfigProperties(LocalConfiguration config)
156: throws Exception {
157: // do nothing
158: }
159:
160: protected void setExtraClasspath(AppServerParameters params) {
161: // do nothing
162: }
163:
164: }
|