KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > test > server > appserver > unit > AbstractAppServerTestCase


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.test.server.appserver.unit;
6
7 import org.apache.commons.io.FileUtils;
8 import org.apache.commons.lang.ClassUtils;
9 import org.apache.tools.ant.Project;
10 import org.apache.tools.ant.taskdefs.Zip;
11
12 import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
13
14 import com.tc.object.config.schema.Lock;
15 import com.tc.object.config.schema.Root;
16 import com.tc.process.LinkedJavaProcessPollingAgent;
17 import com.tc.properties.TCPropertiesImpl;
18 import com.tc.test.TCTestCase;
19 import com.tc.test.TestConfigObject;
20 import com.tc.test.server.Server;
21 import com.tc.test.server.appserver.AppServer;
22 import com.tc.test.server.appserver.AppServerInstallation;
23 import com.tc.test.server.appserver.AppServerResult;
24 import com.tc.test.server.appserver.NewAppServerFactory;
25 import com.tc.test.server.appserver.StandardAppServerParameters;
26 import com.tc.test.server.appserver.war.AbstractDescriptorXml;
27 import com.tc.test.server.appserver.war.War;
28 import com.tc.test.server.dsoserver.DsoServer;
29 import com.tc.test.server.dsoserver.StandardDsoServer;
30 import com.tc.test.server.dsoserver.StandardDsoServerParameters;
31 import com.tc.test.server.tcconfig.StandardTerracottaAppServerConfig;
32 import com.tc.test.server.tcconfig.TerracottaServerConfigGenerator;
33 import com.tc.test.server.util.HttpUtil;
34 import com.tc.test.server.util.VmStat;
35 import com.tc.text.Banner;
36 import com.tc.util.Assert;
37 import com.tc.util.runtime.Os;
38 import com.tc.util.runtime.ThreadDump;
39 import com.terracotta.session.util.ConfigProperties;
40
41 import java.io.File JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.lang.reflect.Modifier JavaDoc;
44 import java.net.MalformedURLException JavaDoc;
45 import java.net.URL JavaDoc;
46 import java.text.SimpleDateFormat JavaDoc;
47 import java.util.ArrayList JavaDoc;
48 import java.util.Date JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.Properties JavaDoc;
52
53 import javax.servlet.http.HttpServlet JavaDoc;
54 import javax.servlet.http.HttpSessionActivationListener JavaDoc;
55 import javax.servlet.http.HttpSessionAttributeListener JavaDoc;
56 import javax.servlet.http.HttpSessionListener JavaDoc;
57
58 /**
59  * Please read this doc in it's entirety before attempting to utilize the Terracotta Appserver Testing Framework and
60  * it's constituent components. The comments below describe the abstract test case itself and explain how it is intended
61  * to be extended, debugged, and automated.
62  * <p>
63  * This class serves as a layer of indirection between unit tests and the terracotta framework for server installation
64  * and invocation. The initialization and execution process is as follows:
65  * <p>
66  * A factory is used to create supporting appserver classes for a given platform. A list of servers is kept for use by
67  * the <tt>tearDown()</tt> method. It is generally advised that <tt>startDsoServer()</tt> be called first followed
68  * by n calls to <tt>startAppServer()</tt> before {@link HttpUtil} is used to page the running servers. This practice
69  * may vary for certain tests that may be expected to fail or timeout. The method <tt>createUrl()</tt> should be
70  * called to obtain a reference to a servlet running in a container. The server port is provided as a field of
71  * {@link AppServerResult} which should be captured and passed to <tt>createUrl()</tt> for that server.
72  * <p>
73  * The framework uses reflection to locate <tt>public static</tt> inner classes that extend {@link HttpServlet} and
74  * end with "servlet" (not case sensitive). These servlets are automatically deployed in a WAR (web application
75  * resource) with the correct servlet mappings and appserver specific descriptors; which are referenced using the
76  * <tt>createUrl()</tt> method. The tc-config.xml file is also auto generated and deployed to each server running dso.
77  * <p>
78  * As a recommended coding practice the inner class servlets should handle the majority of the testing infrastructure;
79  * where possible returning a simple boolean "true" or "false". A mechanism is provided to share properties between the
80  * outer class (unit test) and it's associated servlets in the form of an overloaded <tt>startAppServer()</tt> method
81  * that takes a {@link Properties} file. These properties are available to servlets in that container as system
82  * properties. By default every servlet under this convention is provided a system property for the instance name and
83  * http port. See {@link AppServerConstants} for exact property names.
84  * <p>
85  * The coding guidelines for writting unit tests that interact with inner class servlets are as follows:
86  * <ul>
87  * <li>Servlets are packaged and deployed to the appserver's JVM therefore they know nothing about the outer class or
88  * the unit test which is being run.
89  * <li>A servlet should not utilize any imports unless the imported files are also included in the associated WAR as
90  * libraries.
91  * <li>The servlet should not reference any parent class methods (the outer-class superclass is not even deployed to
92  * the appserver)
93  * </ul>
94  * <p>
95  *
96  * <pre>
97  * outer class:
98  * ...
99  * int port0 = startAppServer(false).serverPort();
100  * boolean[] values = HttpUtil.getBooleanValues(createUrl(port0, SimpleDsoSessionsTest.DsoPingPongServlet.class));
101  * assertTrue(values[0]);
102  * assertFalse(values[1]);
103  * ...
104  * inner class servlet:
105  * ...
106  * response.setContentType(&quot;text/html&quot;);
107  * PrintWriter out = response.getWriter();
108  * out.println(&quot;true&quot;);
109  * out.println(&quot;false&quot;);
110  * ...
111  * </pre>
112  *
113  * <p>
114  * <h3>Debugging Information:</h3>
115  * There are a number of locations and files to consider when debugging appserver unit tests. Below is a list followed
116  * by a more formal description.
117  * <ul>
118  * <li>The console - Provides output for the unit test parent process which includes the DSO server (in red) and the
119  * output known to the parent about the child process appserver startup.
120  * <li>appserver-name.log - located in the sandbox directory of the working instance location which includes all server
121  * output for out and err.
122  * <li>data directory - contains the WAR and tc-config.
123  * </ul>
124  * In general if the console does not sufficiently describe a failure you should open the working instance directory
125  * (see comments below for more info) to confirm that the .log was created for a particular instance. The .log is
126  * created before the appserver is started in the child JVM process. If that does not exist there is something wrong;
127  * probably in the classpath that starts the appserver. If the log does exist it will probably describe the failure or
128  * exception. If no exception is provided try wrapping your servlet content with a try catch block to the extent of
129  * e.printStackTrace().
130  * <p>
131  * <h3>Working Instance Directory</h3>
132  * This directory contains the subdirectories of the sandbox and data. The data directory contains files shared by all
133  * instances of an appserver but is specific to a unit test. These files may include the tc-config.xml file,
134  * testname.war and DSO logs etc. The sandbox directory contains the actual running server instances. Each server is
135  * given a name. By default the convention "node-i" is used. In this location you will find a folder (node-i), a log
136  * (node-i.log), and a properties file (node-i.properties) for each allocated server instance. By default the working
137  * instance is created in the unit test temp directory referred to by {@link TCTestCase.getTempDirectory()} (usually
138  * under build/test/fullclassname). When the monkeys complete a batch run of the unit tests they take the contents of
139  * the temp directory and package them into a jar so that the data is available for review. There is an option to
140  * override the working instance directory in the appserver properties file (generated by the build process). If this
141  * feature is exercised the working instance will run in the specified location. Once complete for that test the
142  * contents will be moved to their proper location in the temp folder. You will only need to override the working
143  * instance location if the path becomes too long on windows systems.
144  * <p>
145  * As a final note: the <tt>UttpUtil</tt> class should be used (and added to as needed) to page servlets and validate
146  * assertions.
147  *
148  * @author eellis
149  */

150 public abstract class AbstractAppServerTestCase extends TCTestCase {
151
152   private static final SynchronizedInt nodeCounter = new SynchronizedInt(-1);
153   private static final String JavaDoc NODE = "node-";
154   private static final String JavaDoc DOMAIN = "localhost";
155
156   protected final List JavaDoc appservers = new ArrayList JavaDoc();
157   private final Object JavaDoc workingDirLock = new Object JavaDoc();
158   private final List JavaDoc dsoServerJvmArgs = new ArrayList JavaDoc();
159   private final List JavaDoc roots = new ArrayList JavaDoc();
160   private final List JavaDoc locks = new ArrayList JavaDoc();
161   private final List JavaDoc includes = new ArrayList JavaDoc();
162
163   private final TestConfigObject config;
164
165   private File JavaDoc serverInstallDir;
166   private File JavaDoc workingDir;
167   private File JavaDoc tempDir;
168   private File JavaDoc bootJar;
169   private NewAppServerFactory appServerFactory;
170   private AppServerInstallation installation;
171   private File JavaDoc warFile;
172   private DsoServer dsoServer;
173   private TerracottaServerConfigGenerator configGen;
174
175   private boolean isSynchronousWrite = false;
176
177   public AbstractAppServerTestCase() {
178     // keep the regular thread dump behavior for windows and macs
179
setDumpThreadsOnTimeout(Os.isWindows() || Os.isMac());
180
181     try {
182       config = TestConfigObject.getInstance();
183     } catch (IOException JavaDoc e) {
184       throw new RuntimeException JavaDoc(e);
185     }
186
187   }
188
189   protected int getJMXPort() {
190     if (configGen == null) { throw new AssertionError JavaDoc(
191                                                       "DSO server is not running so JMX port has not been assigned yet."); }
192     return configGen.getConfig().getJmxPort();
193   }
194
195   protected void setUp() throws Exception JavaDoc {
196     LinkedJavaProcessPollingAgent.startHeartBeatServer();
197     tempDir = getTempDirectory();
198     serverInstallDir = makeDir(config.appserverServerInstallDir());
199     File JavaDoc workDir = new File JavaDoc(config.appserverWorkingDir());
200     try {
201       if (workDir.exists()) {
202         if (workDir.isDirectory()) {
203           FileUtils.cleanDirectory(workDir);
204         } else {
205           throw new RuntimeException JavaDoc(workDir + " exists, but is not a directory");
206         }
207       }
208     } catch (Throwable JavaDoc e) {
209       File JavaDoc prev = workDir;
210       workDir = new File JavaDoc(config.appserverWorkingDir() + "-"
211                          + new SimpleDateFormat JavaDoc("yyyyMMdd-HHmmss").format(new Date JavaDoc()));
212       Banner.warnBanner("Caught IOException setting up workDir as " + prev + ", using " + workDir + " instead");
213     }
214
215     workingDir = makeDir(workDir.getAbsolutePath());
216     bootJar = new File JavaDoc(config.normalBootJar());
217     appServerFactory = NewAppServerFactory.createFactoryFromProperties(config);
218
219     String JavaDoc appserverURLBase = config.appserverURLBase();
220     String JavaDoc appserverHome = config.appserverHome();
221
222     if (appserverHome != null && !appserverHome.trim().equals("")) {
223       File JavaDoc home = new File JavaDoc(appserverHome);
224       installation = appServerFactory.createInstallation(home, workingDir);
225
226     } else if (appserverURLBase != null && !appserverURLBase.trim().equals("")) {
227       URL JavaDoc host = new URL JavaDoc(appserverURLBase);
228       installation = appServerFactory.createInstallation(host, serverInstallDir, workingDir);
229
230     } else {
231       throw new AssertionError JavaDoc(
232                                "No container installation available. You must define one of the following config properties:\n"
233                                    + TestConfigObject.APP_SERVER_HOME + "\nor\n"
234                                    + TestConfigObject.APP_SERVER_REPOSITORY_URL_BASE);
235     }
236   }
237
238   protected final boolean cleanTempDir() {
239     return false;
240   }
241
242   protected void beforeTimeout() throws Throwable JavaDoc {
243     threadDumpGroup();
244
245     // make an archive of the workingDir since it will not be renamed when test times out
246
archiveSandboxLogs();
247   }
248
249   private void archiveSandboxLogs() {
250     synchronized (workingDirLock) {
251       if (installation != null) {
252         String JavaDoc src = installation.sandboxDirectory().getParentFile().getAbsolutePath();
253         String JavaDoc dest = new File JavaDoc(tempDir, "archive-logs-" + System.currentTimeMillis() + ".zip").getAbsolutePath();
254
255         String JavaDoc msg = "\n";
256         msg += "*****************************\n";
257         msg += "* Archiving logs in [" + src + "] to " + dest + "\n";
258         msg += "*****************************\n";
259         System.out.println(msg);
260
261         Zip zip = new Zip();
262         zip.setProject(new Project());
263         zip.setDestFile(new File JavaDoc(dest));
264         zip.setBasedir(new File JavaDoc(src));
265         zip.setIncludes("**/*.log");
266         zip.setUpdate(false);
267         zip.execute();
268       }
269     }
270   }
271
272   /**
273    * Starts a DSO server using a generated tc-config.xml
274    */

275   protected final void startDsoServer() throws Exception JavaDoc {
276     Assert.assertNull(dsoServer);
277     dsoServer = new StandardDsoServer();
278
279     if (dsoServerJvmArgs != null && !dsoServerJvmArgs.isEmpty()) {
280       dsoServer.addJvmArgs(dsoServerJvmArgs);
281     }
282
283     TerracottaServerConfigGenerator generator = configGen();
284
285     File JavaDoc dsoWorkingDir = installation.dataDirectory();
286     File JavaDoc outputFile = new File JavaDoc(dsoWorkingDir, "dso-server.log");
287
288     StandardDsoServerParameters params = new StandardDsoServerParameters(generator, dsoWorkingDir, outputFile,
289                                                                          generator.getConfig().getDsoPort(), generator
290                                                                              .getConfig().getJmxPort());
291
292     dsoServer.start(params);
293   }
294
295   /*
296    * This method should be called before DSO server is started.
297    */

298   protected final void addDsoServerJvmArgs(List JavaDoc jvmArgs) {
299     dsoServerJvmArgs.addAll(jvmArgs);
300   }
301
302   /*
303    * This method should be called before DSO server is started.
304    */

305   protected final void setSynchronousWrite(boolean value) {
306     isSynchronousWrite = value;
307   }
308
309   /*
310    * This method should be called before DSO server is started.
311    */

312   protected final void addRoots(List JavaDoc rootsToAdd) {
313     roots.addAll(rootsToAdd);
314   }
315
316   /*
317    * This method should be called before DSO server is started.
318    */

319   protected final void addLocks(List JavaDoc locksToAdd) {
320     locks.addAll(locksToAdd);
321   }
322
323   protected final void addInclude(String JavaDoc expression) {
324     includes.add(expression);
325   }
326
327   /**
328    * Starts an instance of the assigned default application server listed in testconfig.properties. Servlets and the WAR
329    * are dynamically generated using the convention listed in the header of this document.
330    *
331    * @param dsoEnabled - enable or disable dso for this instance
332    * @return AppServerResult - series of return values including the server port assigned to this instance
333    */

334   protected final AppServerResult startAppServer(boolean dsoEnabled) throws Exception JavaDoc {
335     return startAppServer(dsoEnabled, new Properties());
336   }
337
338   /**
339    * @see startAppServer(boolean dsoEnabled)
340    * @param props - <tt>Properties</tt> available as <tt>System.properties</tt> to servlets delopyed in this
341    * container
342    */

343   protected final AppServerResult startAppServer(boolean dsoEnabled, Properties props) throws Exception JavaDoc {
344     return startAppServer(dsoEnabled, props, null);
345   }
346
347   /**
348    * @see startAppServer(boolean dsoEnabled, Properties props)
349    * @param jvmargs - Array of additional jvm arguments to use when starting the app server
350    */

351   protected final AppServerResult startAppServer(boolean dsoEnabled, Properties props, String JavaDoc[] jvmargs)
352       throws Exception JavaDoc {
353     int nodeNumber = nodeCounter.increment();
354     try {
355       StandardAppServerParameters params;
356       params = (StandardAppServerParameters) appServerFactory.createParameters(NODE + nodeNumber, props);
357       AppServer appServer = appServerFactory.createAppServer(installation);
358
359       if (dsoEnabled) {
360         params.enableDSO(configGen(), bootJar);
361       }
362       if (jvmargs != null) {
363         for (int i = 0; i < jvmargs.length; i++) {
364           params.appendJvmArgs(jvmargs[i]);
365         }
366       }
367
368       params.appendJvmArgs("-DNODE=" + NODE + nodeNumber);
369
370       // params.appendJvmArgs("-Dtc.classloader.writeToDisk=true");
371

372       params.appendJvmArgs("-D" + TCPropertiesImpl.SYSTEM_PROP_PREFIX + "." + ConfigProperties.REQUEST_BENCHES
373                            + "=true");
374
375       params.appendJvmArgs("-verbose:gc");
376       params.appendJvmArgs("-Xloggc:" + new File JavaDoc(this.workingDir, "node-" + nodeNumber + ".gc.log"));
377       params.appendJvmArgs("-XX:+PrintGCDetails");
378
379       if (false && nodeNumber == 0) {
380         int debugPort = 8000 + nodeNumber;
381         System.out.println("Waiting for debugger connection on port " + debugPort);
382         params.appendJvmArgs("-Xdebug");
383         params.appendJvmArgs("-Xrunjdwp:server=y,transport=dt_socket,address=" + debugPort + ",suspend=y");
384       }
385
386       params.addWar(warFile());
387       AppServerResult r = (AppServerResult) appServer.start(params);
388
389       // only add to this collection if start() actually returned w/o an exception
390
appservers.add(appServer);
391       return r;
392     } catch (Exception JavaDoc e) {
393       threadDumpGroup();
394       throw e;
395     }
396   }
397
398   private void threadDumpGroup() {
399     // this is disabled on mac since something in the process group really dislikes kill -3. Eric says every process on
400
// his machine gets killed (terminated) when this goes off
401
if (Os.isUnix() && !Os.isMac()) {
402       ThreadDump.dumpProcessGroup();
403     }
404   }
405
406   /**
407    * @return URL - the correct URL refering to the provied servlet class for the appserver running on the given port
408    */

409   public URL JavaDoc createUrl(int port, Class JavaDoc servletClass, String JavaDoc query) throws MalformedURLException JavaDoc {
410     if (query != null && query.length() > 0) {
411       query = "?" + query;
412     }
413
414     String JavaDoc[] parts = servletClass.getName().split("\\.");
415     String JavaDoc servletUrl = AbstractDescriptorXml.translateUrl(parts[parts.length - 1]);
416     return new URL JavaDoc("http://" + DOMAIN + ":" + port + "/" + testName() + "/" + servletUrl + query);
417   }
418
419   public URL JavaDoc createUrl(int port, Class JavaDoc servletClass) throws MalformedURLException JavaDoc {
420     return createUrl(port, servletClass, "");
421   }
422
423   private boolean awaitShutdown(int timewait) throws Exception JavaDoc {
424     long start = System.currentTimeMillis();
425     boolean foundAlive = false;
426     do {
427       Thread.sleep(1000);
428       foundAlive = LinkedJavaProcessPollingAgent.isAnyAppServerAlive();
429     } while (foundAlive && System.currentTimeMillis() - start < timewait);
430
431     return foundAlive;
432   }
433
434   /**
435    * If overridden <tt>super.tearDown()</tt> must be called to ensure that servers are all shutdown properly
436    *
437    * @throws Exception
438    */

439   protected void tearDown() throws Exception JavaDoc {
440     try {
441       for (Iterator JavaDoc iter = appservers.iterator(); iter.hasNext();) {
442         Server server = (Server) iter.next();
443         server.stop();
444       }
445
446       awaitShutdown(10 * 1000);
447       if (dsoServer != null && dsoServer.isRunning()) dsoServer.stop();
448       System.out.println("Shutdown heartbeat server and its children...");
449       LinkedJavaProcessPollingAgent.shutdown();
450     } finally {
451       VmStat.stop();
452       synchronized (workingDirLock) {
453         File JavaDoc dest = new File JavaDoc(tempDir, getName());
454         System.err.println("Copying files from " + workingDir + " to " + dest);
455         try {
456           com.tc.util.io.FileUtils.copyFile(workingDir, dest);
457         } catch (IOException JavaDoc ioe) {
458           Banner.warnBanner("IOException caught while copying workingDir files");
459           ioe.printStackTrace();
460         }
461
462         System.err.println("Deleting working directory files in " + workingDir);
463         try {
464           FileUtils.forceDelete(workingDir);
465         } catch (IOException JavaDoc ioe) {
466           Banner.warnBanner("IOException caught while deleting workingDir");
467           // print this out, but don't fail test by re-throwing it
468
ioe.printStackTrace();
469         }
470       }
471     }
472   }
473
474   protected final void collectVmStats() throws IOException JavaDoc {
475     VmStat.start(workingDir);
476   }
477
478   private synchronized File JavaDoc warFile() throws Exception JavaDoc {
479     if (warFile != null) return warFile;
480     War war = appServerFactory.createWar(testName());
481     addServletsWebAppClasses(war);
482     File JavaDoc resourceDir = installation.dataDirectory();
483     warFile = new File JavaDoc(resourceDir + File.separator + war.writeWarFileToDirectory(resourceDir));
484     return warFile;
485   }
486
487   private void addServletsWebAppClasses(War war) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
488     Class JavaDoc[] classes = getClass().getClasses();
489     for (int i = 0; i < classes.length; i++) {
490       Class JavaDoc clazz = classes[i];
491       if (!isSafeClass(clazz)) {
492         continue;
493       }
494       if (isServlet(clazz)) {
495         war.addServlet(clazz);
496       }
497       if (isListener(clazz)) {
498         war.addListener(clazz);
499       }
500       if (isFilter(clazz)) {
501         TCServletFilter filterInstance = (TCServletFilter) clazz.newInstance();
502         war.addFilter(clazz, filterInstance.getPattern(), filterInstance.getInitParams());
503       }
504       // it's just a class, add it
505
war.addClass(clazz);
506     }
507   }
508
509   private static boolean isSafeClass(Class JavaDoc clazz) {
510     int mod = clazz.getModifiers();
511     return Modifier.isStatic(mod) && Modifier.isPublic(mod) && !Modifier.isInterface(mod) && !Modifier.isAbstract(mod);
512   }
513
514   private static boolean isServlet(Class JavaDoc clazz) {
515     return clazz.getSuperclass().equals(HttpServlet JavaDoc.class) && clazz.getName().toLowerCase().endsWith("servlet");
516   }
517
518   private static boolean isFilter(Class JavaDoc clazz) {
519     return TCServletFilter.class.isAssignableFrom(clazz);
520   }
521
522   private static boolean isListener(Class JavaDoc clazz) {
523     return HttpSessionActivationListener JavaDoc.class.isAssignableFrom(clazz)
524            || HttpSessionAttributeListener JavaDoc.class.isAssignableFrom(clazz)
525            || HttpSessionListener JavaDoc.class.isAssignableFrom(clazz);
526   }
527
528   private File JavaDoc makeDir(String JavaDoc dirPath) throws IOException JavaDoc {
529     File JavaDoc dir = new File JavaDoc(dirPath);
530     if (dir.exists()) {
531       if (dir.isDirectory()) { return dir; }
532       throw new IOException JavaDoc(dir + " exists, but is not a directory");
533     }
534     boolean created = dir.mkdirs();
535     if (!created) { throw new IOException JavaDoc("Could not create directory " + dir); }
536     return dir;
537   }
538
539   private String JavaDoc testName() {
540     return ClassUtils.getShortClassName(getClass());
541   }
542
543   private synchronized TerracottaServerConfigGenerator configGen() throws Exception JavaDoc {
544     if (configGen != null) { return configGen; }
545     StandardTerracottaAppServerConfig configBuilder = appServerFactory.createTcConfig(installation.dataDirectory());
546
547     if (isSessionTest()) {
548       if (isSynchronousWrite) {
549         configBuilder.addWebApplication(testName(), isSynchronousWrite);
550       } else {
551         configBuilder.addWebApplication(testName());
552       }
553     }
554
555     configBuilder.addInclude("com.tctest..*");
556     configBuilder.addInclude("com.tctest..*$*");
557
558     for (Iterator JavaDoc iter = includes.iterator(); iter.hasNext();) {
559       configBuilder.addInclude((String JavaDoc) iter.next());
560     }
561
562     for (Iterator JavaDoc iter = roots.iterator(); iter.hasNext();) {
563       Root root = (Root) iter.next();
564       configBuilder.addRoot(root.fieldName(), root.rootName());
565     }
566
567     for (Iterator JavaDoc iter = locks.iterator(); iter.hasNext();) {
568       Lock lock = (Lock) iter.next();
569       String JavaDoc lockName = null;
570       if (!lock.isAutoLock()) {
571         lockName = lock.lockName();
572       }
573       configBuilder.addLock(lock.isAutoLock(), lock.methodExpression(), lock.lockLevel().toString(), lockName);
574     }
575
576     return configGen = new TerracottaServerConfigGenerator(installation.dataDirectory(), configBuilder);
577   }
578
579   protected boolean isSessionTest() {
580     return true;
581   }
582 }
583
Popular Tags