001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.test.activepassive;
006:
007: import com.tc.config.schema.setup.TestTVSConfigurationSetupManagerFactory;
008: import com.tc.management.JMXConnectorProxy;
009: import com.tc.management.beans.L2DumperMBean;
010: import com.tc.management.beans.L2MBeanNames;
011: import com.tc.management.beans.TCServerInfoMBean;
012: import com.tc.objectserver.control.ExtraProcessServerControl;
013: import com.tc.objectserver.control.ServerControl;
014: import com.tc.util.PortChooser;
015: import com.tc.util.concurrent.ThreadUtil;
016: import com.tctest.TestState;
017:
018: import java.io.File;
019: import java.io.FileNotFoundException;
020: import java.io.IOException;
021: import java.security.SecureRandom;
022: import java.util.ArrayList;
023: import java.util.List;
024: import java.util.Random;
025:
026: import javax.management.MBeanServerConnection;
027: import javax.management.MBeanServerInvocationHandler;
028: import javax.management.remote.JMXConnector;
029:
030: public class ActivePassiveServerManager {
031: private static final String HOST = "localhost";
032: private static final String SERVER_NAME = "testserver";
033: private static final String CONFIG_FILE_NAME = "active-passive-server-config.xml";
034: private static final boolean DEBUG = false;
035: private static final int NULL_VAL = -1;
036:
037: private final File tempDir;
038: private final PortChooser portChooser;
039: private final String configModel;
040: private final ActivePassiveTestSetupManager setupManger;
041:
042: private final int serverCount;
043: private final String serverCrashMode;
044: private final long serverCrashWaitTimeInSec;
045: private final String serverPersistence;
046: private final boolean serverNetworkShare;
047: private final ActivePassiveServerConfigCreator serverConfigCreator;
048: private final String configFileLocation;
049: private final File configFile;
050:
051: private final ServerInfo[] servers;
052: private final int[] dsoPorts;
053: private final int[] jmxPorts;
054: private final int[] l2GroupPorts;
055: private final String[] serverNames;
056: private final TCServerInfoMBean[] tcServerInfoMBeans;
057: private final JMXConnector[] jmxConnectors;
058:
059: private final List errors;
060:
061: private int activeIndex = NULL_VAL;
062: private int lastCrashedIndex = NULL_VAL;
063: private ActivePassiveServerCrasher serverCrasher;
064: private int maxCrashCount;
065: private final TestState testState;
066: private Random random;
067: private long seed;
068: private final File javaHome;
069: private int pid = -1;
070: private List jvmArgs = null;
071:
072: public ActivePassiveServerManager(boolean isActivePassiveTest,
073: File tempDir, PortChooser portChooser, String configModel,
074: ActivePassiveTestSetupManager setupManger, File javaHome,
075: TestTVSConfigurationSetupManagerFactory configFactory)
076: throws Exception {
077: this (isActivePassiveTest, tempDir, portChooser, configModel,
078: setupManger, javaHome, configFactory, new ArrayList());
079:
080: }
081:
082: public ActivePassiveServerManager(boolean isActivePassiveTest,
083: File tempDir, PortChooser portChooser, String configModel,
084: ActivePassiveTestSetupManager setupManger, File javaHome,
085: TestTVSConfigurationSetupManagerFactory configFactory,
086: List extraJvmArgs) throws Exception {
087: this .jvmArgs = extraJvmArgs;
088:
089: if (!isActivePassiveTest) {
090: throw new AssertionError(
091: "A non-ActivePassiveTest is trying to use this class.");
092: }
093:
094: this .setupManger = setupManger;
095:
096: serverCount = this .setupManger.getServerCount();
097:
098: if (serverCount < 2) {
099: throw new AssertionError(
100: "Active-passive tests involve 2 or more DSO servers: serverCount=["
101: + serverCount + "]");
102: }
103:
104: this .tempDir = tempDir;
105: configFileLocation = this .tempDir + File.separator
106: + CONFIG_FILE_NAME;
107: configFile = new File(configFileLocation);
108:
109: this .portChooser = portChooser;
110: this .configModel = configModel;
111:
112: serverCrashMode = this .setupManger.getServerCrashMode();
113: serverCrashWaitTimeInSec = this .setupManger
114: .getServerCrashWaitTimeInSec();
115: maxCrashCount = this .setupManger.getMaxCrashCount();
116: serverPersistence = this .setupManger.getServerPersistenceMode();
117: serverNetworkShare = this .setupManger.isNetworkShare();
118:
119: servers = new ServerInfo[this .serverCount];
120: dsoPorts = new int[this .serverCount];
121: jmxPorts = new int[this .serverCount];
122: l2GroupPorts = new int[this .serverCount];
123: serverNames = new String[this .serverCount];
124: tcServerInfoMBeans = new TCServerInfoMBean[this .serverCount];
125: jmxConnectors = new JMXConnector[this .serverCount];
126: createServers();
127:
128: serverConfigCreator = new ActivePassiveServerConfigCreator(
129: this .serverCount, dsoPorts, jmxPorts, l2GroupPorts,
130: serverNames, serverPersistence, serverNetworkShare,
131: this .configModel, configFile, this .tempDir,
132: configFactory);
133: serverConfigCreator.writeL2Config();
134:
135: errors = new ArrayList();
136: testState = new TestState();
137: this .javaHome = javaHome;
138:
139: if (serverCrashMode
140: .equals(ActivePassiveCrashMode.RANDOM_SERVER_CRASH)) {
141: SecureRandom srandom = SecureRandom.getInstance("SHA1PRNG");
142: seed = srandom.nextLong();
143: random = new Random(seed);
144: System.out.println("***** Random number generator seed=["
145: + seed + "]");
146: }
147: }
148:
149: private void resetActiveIndex() {
150: activeIndex = NULL_VAL;
151: }
152:
153: private void resetLastCrashedIndex() {
154: lastCrashedIndex = NULL_VAL;
155: }
156:
157: private void createServers() throws FileNotFoundException {
158: int startIndex = 0;
159:
160: if (DEBUG) {
161: dsoPorts[0] = 8510;
162: jmxPorts[0] = 8520;
163: l2GroupPorts[0] = 8530;
164: serverNames[0] = SERVER_NAME + 0;
165: servers[0] = new ServerInfo(HOST, serverNames[0],
166: dsoPorts[0], jmxPorts[0], l2GroupPorts[0],
167: getServerControl(dsoPorts[0], jmxPorts[0],
168: serverNames[0]));
169: dsoPorts[1] = 7510;
170: jmxPorts[1] = 7520;
171: l2GroupPorts[1] = 7530;
172: serverNames[1] = SERVER_NAME + 1;
173: servers[1] = new ServerInfo(HOST, serverNames[1],
174: dsoPorts[1], jmxPorts[1], l2GroupPorts[1],
175: getServerControl(dsoPorts[1], jmxPorts[1],
176: serverNames[1]));
177: if (dsoPorts.length > 2) {
178: dsoPorts[2] = 6510;
179: jmxPorts[2] = 6520;
180: l2GroupPorts[2] = 6530;
181: serverNames[2] = SERVER_NAME + 2;
182: servers[2] = new ServerInfo(HOST, serverNames[2],
183: dsoPorts[2], jmxPorts[2], l2GroupPorts[2],
184: getServerControl(dsoPorts[2], jmxPorts[2],
185: serverNames[2]));
186: }
187:
188: startIndex = 3;
189: }
190:
191: for (int i = startIndex; i < dsoPorts.length; i++) {
192: setPorts(i);
193: serverNames[i] = SERVER_NAME + i;
194: servers[i] = new ServerInfo(HOST, serverNames[i],
195: dsoPorts[i], jmxPorts[i], l2GroupPorts[i],
196: getServerControl(dsoPorts[i], jmxPorts[i],
197: serverNames[i]));
198: }
199: }
200:
201: private void setPorts(int index) {
202: while (true) {
203: int newPort = portChooser.chooseRandomPort();
204: if (isUnusedPort(newPort)) {
205: jmxPorts[index] = newPort;
206: break;
207: }
208: }
209: while (true) {
210: int newPort = portChooser.chooseRandomPort();
211: if (newPort == PortChooser.MAX) {
212: continue;
213: }
214: if (portChooser.isPortUsed(newPort + 1)) {
215: continue;
216: }
217: if (isUnusedPort(newPort) && isUnusedPort(newPort + 1)) {
218: dsoPorts[index] = newPort;
219: l2GroupPorts[index] = newPort + 1;
220: break;
221: }
222: }
223: }
224:
225: private boolean isUnusedPort(int port) {
226: boolean unused = true;
227: for (int i = 0; i < dsoPorts.length; i++) {
228: if (dsoPorts[i] == port) {
229: unused = false;
230: }
231: }
232: for (int i = 0; i < jmxPorts.length; i++) {
233: if (jmxPorts[i] == port) {
234: unused = false;
235: }
236: }
237: for (int i = 0; i < l2GroupPorts.length; i++) {
238: if (l2GroupPorts[i] == port) {
239: unused = false;
240: }
241: }
242: return unused;
243: }
244:
245: private ServerControl getServerControl(int dsoPort, int jmxPort,
246: String serverName) throws FileNotFoundException {
247: return new ExtraProcessServerControl(HOST, dsoPort, jmxPort,
248: configFileLocation, true, serverName, this .jvmArgs,
249: javaHome, true);
250: }
251:
252: public void startServers() throws Exception {
253: if (activeIndex >= 0) {
254: throw new AssertionError(
255: "Server(s) has/have been already started");
256: }
257:
258: for (int i = 0; i < servers.length; i++) {
259: servers[i].getServerControl().start();
260: }
261: Thread.sleep(500 * servers.length);
262:
263: debugPrintln("***** startServers(): about to search for active threadId=["
264: + Thread.currentThread().getName() + "]");
265:
266: for (int i = 0; i < tcServerInfoMBeans.length; i++) {
267: debugPrintln("***** Caching tcServerInfoMBean for server=["
268: + dsoPorts[i] + "]");
269: tcServerInfoMBeans[i] = getTcServerInfoMBean(i);
270: }
271:
272: activeIndex = getActiveIndex();
273:
274: if (serverCrashMode
275: .equals(ActivePassiveCrashMode.CONTINUOUS_ACTIVE_CRASH)
276: || serverCrashMode
277: .equals(ActivePassiveCrashMode.RANDOM_SERVER_CRASH)) {
278: startContinuousCrash();
279: }
280: }
281:
282: private void startContinuousCrash() {
283: serverCrasher = new ActivePassiveServerCrasher(this ,
284: serverCrashWaitTimeInSec, maxCrashCount, testState);
285: new Thread(serverCrasher).start();
286: }
287:
288: public void storeErrors(Exception e) {
289: if (e != null) {
290: synchronized (errors) {
291: errors.add(e);
292: }
293: }
294: }
295:
296: public List getErrors() {
297: synchronized (errors) {
298: List l = new ArrayList();
299: l.addAll(errors);
300: return l;
301: }
302: }
303:
304: private int getActiveIndex() throws Exception {
305: int index = -1;
306: while (index < 0) {
307: System.out.println("Searching for active server... ");
308: for (int i = 0; i < jmxPorts.length; i++) {
309: if (i != lastCrashedIndex) {
310: if (!servers[i].getServerControl().isRunning()) {
311: throw new AssertionError("Server["
312: + servers[i].getDsoPort()
313: + "] is not running as expected!");
314: }
315: boolean isActive;
316: try {
317: isActive = tcServerInfoMBeans[i].isActive();
318: } catch (Exception e) {
319: System.out
320: .println("Need to fetch tcServerInfoMBean for server=["
321: + dsoPorts[i] + "]...");
322: tcServerInfoMBeans[i] = getTcServerInfoMBean(i);
323: isActive = tcServerInfoMBeans[i].isActive();
324: }
325: debugPrintln("******** index=[" + index + "] i=["
326: + i + "] active=[" + isActive
327: + "] threadId=["
328: + Thread.currentThread().getName() + "]");
329:
330: if (isActive) {
331: if (index < 0) {
332: index = i;
333: debugPrintln("***** active found index=["
334: + index + "]");
335: } else {
336: throw new Exception(
337: "More than one active server found.");
338: }
339: }
340: }
341: }
342: Thread.sleep(1000);
343: }
344: return index;
345: }
346:
347: private void debugPrintln(String s) {
348: if (DEBUG) {
349: System.err.println(s);
350: }
351: }
352:
353: private void waitForPassive() throws Exception {
354: while (true) {
355: System.out
356: .println("Searching for appropriate passive server(s)... ");
357: for (int i = 0; i < jmxPorts.length; i++) {
358: if (i != activeIndex) {
359: if (!servers[i].getServerControl().isRunning()) {
360: throw new AssertionError("Server["
361: + servers[i].getDsoPort()
362: + "] is not running as expected!");
363: }
364: boolean isPassiveStandby;
365: try {
366: isPassiveStandby = tcServerInfoMBeans[i]
367: .isPassiveStandby();
368: } catch (Exception e) {
369: System.out
370: .println("Need to fetch tcServerInfoMBean for server=["
371: + dsoPorts[i] + "]...");
372: tcServerInfoMBeans[i] = getTcServerInfoMBean(i);
373: isPassiveStandby = tcServerInfoMBeans[i]
374: .isPassiveStandby();
375: }
376: if (serverNetworkShare && isPassiveStandby) {
377: return;
378: } else if (!serverNetworkShare
379: && tcServerInfoMBeans[i].isStarted()) {
380: return;
381: } else if (tcServerInfoMBeans[i].isActive()) {
382: throw new AssertionError(
383: "Server["
384: + servers[i].getDsoPort()
385: + "] is in active mode when it should not be!");
386: }
387: }
388: }
389: Thread.sleep(1000);
390: }
391: }
392:
393: private TCServerInfoMBean getTcServerInfoMBean(int index)
394: throws IOException {
395: if (jmxConnectors[index] != null) {
396: closeJMXConnector(index);
397: }
398: jmxConnectors[index] = getJMXConnector(jmxPorts[index]);
399: MBeanServerConnection mBeanServer = jmxConnectors[index]
400: .getMBeanServerConnection();
401: return (TCServerInfoMBean) MBeanServerInvocationHandler
402: .newProxyInstance(mBeanServer,
403: L2MBeanNames.TC_SERVER_INFO,
404: TCServerInfoMBean.class, true);
405: }
406:
407: public static JMXConnector getJMXConnector(int jmxPort)
408: throws IOException {
409: JMXConnector jmxConnector = new JMXConnectorProxy(HOST, jmxPort);
410: jmxConnector.connect();
411: return jmxConnector;
412: }
413:
414: public void stopAllServers() throws Exception {
415: synchronized (testState) {
416: debugPrintln("***** setting TestState to STOPPING");
417: testState.setTestState(TestState.STOPPING);
418:
419: closeJMXConnectors();
420:
421: for (int i = 0; i < serverCount; i++) {
422: debugPrintln("***** stopping server=["
423: + servers[i].getDsoPort() + "]");
424: ServerControl sc = servers[i].getServerControl();
425:
426: if (!sc.isRunning()) {
427: if (i == lastCrashedIndex) {
428: continue;
429: } else {
430: throw new AssertionError("Server["
431: + servers[i].getDsoPort()
432: + "] is not running as expected!");
433: }
434: }
435:
436: if (i == activeIndex) {
437: sc.shutdown();
438: continue;
439: }
440:
441: try {
442: sc.crash();
443: } catch (Exception e) {
444: if (DEBUG) {
445: e.printStackTrace();
446: }
447: }
448: }
449: }
450: }
451:
452: public void dumpAllServers(int currentPid, int dumpCount,
453: long dumpInterval) throws Exception {
454: pid = currentPid;
455: for (int i = 0; i < serverCount; i++) {
456: if (!serverNetworkShare && i != activeIndex) {
457: debugPrintln("***** skipping dumping server=["
458: + dsoPorts[i] + "]");
459: continue;
460: }
461: if (servers[i].getServerControl().isRunning()) {
462: System.out.println("Dumping server=[" + dsoPorts[i]
463: + "]");
464:
465: MBeanServerConnection mbs;
466: try {
467: mbs = jmxConnectors[i].getMBeanServerConnection();
468: } catch (IOException ioe) {
469: System.out
470: .println("Need to recreate jmxConnector for server=["
471: + dsoPorts[i] + "]...");
472: jmxConnectors[i] = getJMXConnector(jmxPorts[i]);
473: mbs = jmxConnectors[i].getMBeanServerConnection();
474: }
475: L2DumperMBean mbean = (L2DumperMBean) MBeanServerInvocationHandler
476: .newProxyInstance(mbs, L2MBeanNames.DUMPER,
477: L2DumperMBean.class, true);
478: mbean.doServerDump();
479: if (pid != 0) {
480: mbean.setThreadDumpCount(dumpCount);
481: mbean.setThreadDumpInterval(dumpInterval);
482: System.out.println("Thread dumping server=["
483: + dsoPorts[i] + "] pid=[" + pid + "]");
484: pid = mbean.doThreadDump();
485: }
486: }
487: }
488: closeJMXConnectors();
489: }
490:
491: private void closeJMXConnector(int i) {
492: if (jmxConnectors[i] != null) {
493: try {
494: jmxConnectors[i].close();
495: } catch (Exception e) {
496: System.out.println("JMXConnector for server=["
497: + dsoPorts[i] + "] already closed.");
498: e.printStackTrace();
499: }
500: jmxConnectors[i] = null;
501: }
502: }
503:
504: private void closeJMXConnectors() {
505: for (int i = 0; i < jmxConnectors.length; i++) {
506: closeJMXConnector(i);
507: ThreadUtil.reallySleep(100);
508: }
509: }
510:
511: public int getPid() {
512: return pid;
513: }
514:
515: public void crashActive() throws Exception {
516: if (!testState.isRunning()) {
517: debugPrintln("***** test state is not running ... skipping crash active");
518: return;
519: }
520:
521: if (activeIndex < 0) {
522: throw new AssertionError("Active index was not set.");
523: }
524:
525: System.out.println("Crashing active server: dsoPort=["
526: + servers[activeIndex].getDsoPort() + "]");
527:
528: debugPrintln("***** wait to find an appropriate passive server.");
529: waitForPassive();
530: debugPrintln("***** finished waiting to find an appropriate passive server.");
531:
532: verifyActiveServerState();
533:
534: ServerControl server = servers[activeIndex].getServerControl();
535: server.crash();
536: debugPrintln("***** Sleeping after crashing active server ");
537: waitForServerCrash(server);
538: debugPrintln("***** Done sleeping after crashing active server ");
539:
540: lastCrashedIndex = activeIndex;
541: resetActiveIndex();
542: debugPrintln("***** lastCrashedIndex[" + lastCrashedIndex
543: + "] ");
544:
545: debugPrintln("***** about to search for active threadId=["
546: + Thread.currentThread().getName() + "]");
547: activeIndex = getActiveIndex();
548: debugPrintln("***** activeIndex[" + activeIndex + "] ");
549: }
550:
551: private void verifyActiveServerState() throws Exception {
552: ServerControl server = servers[activeIndex].getServerControl();
553: if (!server.isRunning()) {
554: throw new AssertionError("Server["
555: + servers[activeIndex].getDsoPort()
556: + "] is not running as expected!");
557: }
558: MBeanServerConnection mbs = jmxConnectors[activeIndex]
559: .getMBeanServerConnection();
560: TCServerInfoMBean mbean = (TCServerInfoMBean) MBeanServerInvocationHandler
561: .newProxyInstance(mbs, L2MBeanNames.TC_SERVER_INFO,
562: TCServerInfoMBean.class, true);
563: if (!mbean.isActive()) {
564: closeJMXConnector(activeIndex);
565: throw new AssertionError("Server["
566: + servers[activeIndex].getDsoPort()
567: + "] is not an active server as expected!");
568: }
569: closeJMXConnector(activeIndex);
570: }
571:
572: private void waitForServerCrash(ServerControl server)
573: throws Exception {
574: long duration = 10000;
575: long startTime = System.currentTimeMillis();
576: while (duration > (System.currentTimeMillis() - startTime)) {
577: if (server.isRunning()) {
578: try {
579: Thread.sleep(1000);
580: } catch (Exception e) {/**/
581: }
582: } else {
583: return;
584: }
585: }
586: throw new Exception("Server crash did not complete.");
587: }
588:
589: private void crashPassive(int passiveToCrash) throws Exception {
590: if (!testState.isRunning()) {
591: debugPrintln("***** test state is not running ... skipping crash passive");
592: return;
593: }
594:
595: System.out.println("Crashing passive server: dsoPort=["
596: + servers[passiveToCrash].getDsoPort() + "]");
597:
598: debugPrintln("***** Closing passive's jmxConnector ");
599: closeJMXConnector(passiveToCrash);
600:
601: ServerControl server = servers[passiveToCrash]
602: .getServerControl();
603: if (!server.isRunning()) {
604: throw new AssertionError("Server["
605: + servers[passiveToCrash].getDsoPort()
606: + "] is not running as expected!");
607: }
608: server.crash();
609: debugPrintln("***** Sleeping after crashing passive server ");
610: waitForServerCrash(server);
611: debugPrintln("***** Done sleeping after crashing passive server ");
612:
613: lastCrashedIndex = passiveToCrash;
614: debugPrintln("***** lastCrashedIndex[" + lastCrashedIndex
615: + "] ");
616: }
617:
618: private void crashRandomServer() throws Exception {
619: if (!testState.isRunning()) {
620: debugPrintln("***** test state is not running ... skipping crash random server");
621: return;
622: }
623:
624: if (activeIndex < 0) {
625: throw new AssertionError("Active index was not set.");
626: }
627: if (random == null) {
628: throw new AssertionError(
629: "Random number generator was not set.");
630: }
631:
632: debugPrintln("***** Choosing random server... ");
633:
634: int crashIndex = random.nextInt(serverCount);
635:
636: if (crashIndex == activeIndex) {
637: crashActive();
638: } else {
639: crashPassive(crashIndex);
640: }
641: }
642:
643: public void restartLastCrashedServer() throws Exception {
644: if (!testState.isRunning()) {
645: debugPrintln("***** test state is not running ... skipping restart");
646: return;
647: }
648:
649: debugPrintln("***** restarting crashed server");
650:
651: if (lastCrashedIndex >= 0) {
652: if (servers[lastCrashedIndex].getServerControl()
653: .isRunning()) {
654: throw new AssertionError("Server["
655: + servers[lastCrashedIndex].getDsoPort()
656: + "] is not down as expected!");
657: }
658: servers[lastCrashedIndex].getServerControl().start();
659:
660: if (!servers[lastCrashedIndex].getServerControl()
661: .isRunning()) {
662: throw new AssertionError("Server["
663: + servers[lastCrashedIndex].getDsoPort()
664: + "] is not running as expected!");
665: }
666: resetLastCrashedIndex();
667: } else {
668: throw new AssertionError("No crashed servers to restart.");
669: }
670: }
671:
672: public int getServerCount() {
673: return serverCount;
674: }
675:
676: public int[] getDsoPorts() {
677: return dsoPorts;
678: }
679:
680: public int[] getJmxPorts() {
681: return jmxPorts;
682: }
683:
684: public boolean crashActiveServerAfterMutate() {
685: if (serverCrashMode
686: .equals(ActivePassiveCrashMode.CRASH_AFTER_MUTATE)) {
687: return true;
688: }
689: return false;
690: }
691:
692: public void addServersToL1Config(
693: TestTVSConfigurationSetupManagerFactory configFactory) {
694: for (int i = 0; i < serverCount; i++) {
695:
696: debugPrintln("******* adding to L1 config: serverName=["
697: + serverNames[i] + "] dsoPort=[" + dsoPorts[i]
698: + "] jmxPort=[" + jmxPorts[i] + "]");
699:
700: configFactory.addServerToL1Config(serverNames[i],
701: dsoPorts[i], jmxPorts[i]);
702: }
703: }
704:
705: public void crashServer() throws Exception {
706: if (serverCrashMode
707: .equals(ActivePassiveCrashMode.CONTINUOUS_ACTIVE_CRASH)) {
708: crashActive();
709: } else if (serverCrashMode
710: .equals(ActivePassiveCrashMode.RANDOM_SERVER_CRASH)) {
711: crashRandomServer();
712: }
713:
714: if (serverNetworkShare
715: && serverPersistence
716: .equals(ActivePassivePersistenceMode.PERMANENT_STORE)) {
717: System.out.println("Deleting data directory for server=["
718: + servers[lastCrashedIndex].getDsoPort() + "]");
719: deleteDirectory(serverConfigCreator
720: .getDataLocation(lastCrashedIndex));
721: }
722: }
723:
724: private void deleteDirectory(String directory) {
725: debugPrintln("\n ##### about to delete dataFile=[" + directory
726: + "] and all of its content...");
727: File[] files = new File(directory).listFiles();
728: for (int i = 0; i < files.length; i++) {
729: if (files[i].isDirectory()) {
730: deleteDirectory(files[i].getAbsolutePath());
731: } else {
732: boolean successful = files[i].delete();
733: if (!successful) {
734: throw new AssertionError("delete file=["
735: + files[i].getAbsolutePath() + "] failed");
736: }
737: debugPrintln("\n ##### deleted file=["
738: + files[i].getAbsolutePath() + "]");
739: }
740: }
741: if (!(new File(directory).delete())) {
742: throw new AssertionError("delete file=[" + directory
743: + "] failed");
744: }
745: debugPrintln("\n ##### deleted directory=[" + directory + "]");
746: debugPrintln("\n ##### dataFile=[" + directory
747: + "] still exists? [" + (new File(directory).exists())
748: + "]");
749: }
750:
751: /*
752: * Server inner class
753: */
754: private static class ServerInfo {
755: private final String server_host;
756: private final String server_name;
757: private final int server_dsoPort;
758: private final int server_jmxPort;
759: private final int server_l2GroupPort;
760: private final ServerControl serverControl;
761: private String dataLocation;
762: private String logLocation;
763:
764: ServerInfo(String host, String name, int dsoPort, int jmxPort,
765: int l2GroupPort, ServerControl serverControl) {
766: server_host = host;
767: server_name = name;
768: server_dsoPort = dsoPort;
769: server_jmxPort = jmxPort;
770: server_l2GroupPort = l2GroupPort;
771: this .serverControl = serverControl;
772: }
773:
774: public String getHost() {
775: return server_host;
776: }
777:
778: public String getName() {
779: return server_name;
780: }
781:
782: public int getDsoPort() {
783: return server_dsoPort;
784: }
785:
786: public int getJmxPort() {
787: return server_jmxPort;
788: }
789:
790: public int getL2GroupPort() {
791: return server_l2GroupPort;
792: }
793:
794: public ServerControl getServerControl() {
795: return serverControl;
796: }
797:
798: public void setDataLocation(String location) {
799: dataLocation = location;
800: }
801:
802: public String getDataLocation() {
803: return dataLocation;
804: }
805:
806: public void setLogLocation(String location) {
807: logLocation = location;
808: }
809:
810: public String getLogLocation() {
811: return logLocation;
812: }
813: }
814:
815: }
|