KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > reporter > ArchiveUtil


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

5 package com.tc.reporter;
6
7 import org.apache.xmlbeans.XmlException;
8
9 import com.tc.config.Loader;
10 import com.tc.config.schema.dynamic.ParameterSubstituter;
11 import com.tc.sysinfo.EnvStats;
12 import com.tc.util.ArchiveBuilder;
13 import com.tc.util.ZipBuilder;
14 import com.terracottatech.config.Client;
15 import com.terracottatech.config.Server;
16 import com.terracottatech.config.Servers;
17 import com.terracottatech.config.TcConfigDocument.TcConfig;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.text.DateFormat JavaDoc;
22 import java.text.SimpleDateFormat JavaDoc;
23 import java.util.Date JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Set JavaDoc;
26
27 import javax.xml.namespace.QName JavaDoc;
28
29 /**
30  * This utility is used to archive Terracotta execution environment information for debugging purposes. Run the
31  * <tt>main()</tt> with no arguments for usage.
32  */

33 public final class ArchiveUtil {
34
35   private final boolean isFull;
36   private final boolean isClient;
37   private final File JavaDoc tcConfig;
38   private final File JavaDoc archiveFile;
39   private static final String JavaDoc STDOUT = "stdout:";
40   private static final String JavaDoc STDERR = "stderr:";
41   private static final String JavaDoc ARCHIVE_FILE_NAME = "tc-archive";
42   private static final String JavaDoc INVALID = "Invalid Arguments:\n\n";
43   private static final String JavaDoc DASH_N = "-n";
44   private static final String JavaDoc DASH_C = "-c";
45   private static final String JavaDoc USAGE = "** Terracotta Archive Tool **\n\n"
46                                                     + "A utility for archiving Terracotta environment information.\n\n"
47                                                     + "\tValid Arguments are:\n\n\t["
48                                                     + DASH_N
49                                                     + "] (No Data - excludes data files)\n\t["
50                                                     + DASH_C
51                                                     + "] (Client - include files from the dso client)"
52                                                     + "\n\t<path to terracotta config xml file (tc-config.xml)>"
53                                                     + " | <path to data and/or logs directory>"
54                                                     + "\n\t[<output filename in .zip format>]\n\nExamples:\n\n\t"
55                                                     + "# java "
56                                                     + ArchiveUtil.class.getName()
57                                                     + " tc-config.xml /home/someuser/tc-archive_server.zip"
58                                                     + "\n\tor\n\t# java "
59                                                     + ArchiveUtil.class.getName()
60                                                     + " /export1/terracotta/server-logs"
61                                                     + "\n\nUsage Summary:\n\n\tTypically you will use this tool to create a full "
62                                                     + "archive of the Terracotta server instance.\n\t"
63                                                     + "You may also want to create archives on the DSO client machines using"
64                                                     + " the -c option. There are two\n\tscenarios where you may "
65                                                     + "need to use the directory location instead of the config file path."
66                                                     + "\n\n\t\t1. The DSO client may not have a local copy of the tc-config.xml"
67                                                     + "\n\t\t2. The tc-config.xml logs and data elements may contain wildcards"
68                                                     + " which use timestamps or \n\t\t environment variables which cannot be"
69                                                     + " resolved.\n\nNotes:\n\n\tThe execution command may vary:"
70                                                     + "\n\t\t# ./archive-util ...\n\n\tSpecifying a directory location as the"
71                                                     + " first command will recursively archive it's entire contents";
72
73   private static final Set JavaDoc validDashArgs = new HashSet JavaDoc();
74   static {
75     validDashArgs.add(DASH_N);
76     validDashArgs.add(DASH_C);
77   }
78
79   private ArchiveUtil(boolean isFull, boolean isClient, File JavaDoc archivePath, File JavaDoc fileName) {
80     this.isFull = isFull;
81     this.isClient = isClient;
82     this.tcConfig = archivePath;
83     if (fileName == null) {
84       File JavaDoc userDir = new File JavaDoc(System.getProperty("user.dir"));
85       if (!userDir.exists()) throw new RuntimeException JavaDoc(
86           "Unexpected error - system property user.dir does not resolve to an actual directory: " + userDir);
87       DateFormat JavaDoc df = new SimpleDateFormat JavaDoc("y-M-d");
88       String JavaDoc name = ARCHIVE_FILE_NAME + "_" + df.format(new Date JavaDoc(System.currentTimeMillis())) + ".zip";
89       this.archiveFile = new File JavaDoc(userDir + File.separator + name);
90     } else {
91       this.archiveFile = fileName;
92     }
93   }
94
95   private static void quit(String JavaDoc msg) {
96     System.err.println(msg);
97     System.exit(0);
98   }
99
100   private static void escape(String JavaDoc msg, Exception JavaDoc e) {
101     System.out.println(INVALID + msg);
102     if (e != null) e.printStackTrace();
103     System.exit(0);
104   }
105
106   public static void main(String JavaDoc[] args) {
107     if (args.length < 1) escape(USAGE, null);
108     boolean dashArgs = true;
109     int locationCmd = -1;
110     int fileArg = -1;
111     Set JavaDoc dashSet = new HashSet JavaDoc(2);
112     for (int i = 0; i < args.length; i++) {
113       if (args[i].startsWith("-")) {
114         if (!dashArgs) escape(USAGE, null);
115         if (validDashArgs.contains(args[i])) dashSet.add(args[i]);
116         else escape(USAGE, null);
117       } else {
118         dashArgs = false;
119         if (fileArg + locationCmd > 1) escape(USAGE, null);
120         if (locationCmd < 0) locationCmd = i;
121         else if (fileArg < 0) fileArg = i;
122         if (fileArg + locationCmd == -2) escape(USAGE, null);
123       }
124     }
125     if (dashSet.size() > 2) escape(USAGE, null);
126     boolean dashC = dashSet.contains(DASH_C);
127     boolean dashN = dashSet.contains(DASH_N);
128
129     if (locationCmd < 0) escape(
130         "Please specify the Terracotta config file location or logs/data directory location\n\n" + USAGE, null);
131     File JavaDoc tcConfigFile = new File JavaDoc(args[locationCmd]);
132     if (!tcConfigFile.exists()) escape("\tTerracotta Configuration file: " + tcConfigFile + "\n\tdoes not exist\n\n"
133         + USAGE, null);
134     File JavaDoc outputFile = null;
135     if (fileArg > 0) {
136       outputFile = new File JavaDoc(new File JavaDoc(args[fileArg]).getAbsolutePath());
137       if (!new File JavaDoc(outputFile.getParent()).exists()) escape(
138           "\tThe directory specified for the output file does not exist", null);
139     }
140     try {
141       new ArchiveUtil(!dashN, dashC, tcConfigFile, outputFile).createArchive();
142     } catch (IOException JavaDoc e) {
143       escape("\tUnable to read Terracotta configuration file\n", e);
144     } catch (XmlException e) {
145       escape("\tUnable to parse Terracotta configuration file\n", e);
146     }
147   }
148
149   private File JavaDoc makeAbsolute(File JavaDoc file) {
150     if (file.isAbsolute()) return file;
151     return new File JavaDoc(tcConfig.getParent() + File.separator + file);
152   }
153
154   private File JavaDoc getClientLogsLocation(TcConfig configBeans) throws IOException JavaDoc, XmlException {
155     Client clients = configBeans.getClients();
156     if (clients == null) quit("The Terracotta config specified doesn't contain the <clients> element.\nYou may have provided a server config by mistake.");
157     String JavaDoc logs = clients.getLogs();
158     if (isStdX(logs)) return null;
159     if (logs == null) logs = Client.type.getElementProperty(QName.valueOf("logs")).getDefaultText();
160     String JavaDoc clientLogs = ParameterSubstituter.substitute(logs);
161     File JavaDoc clientLogsDir = makeAbsolute(new File JavaDoc(clientLogs));
162     if (!clientLogsDir.exists()) quit("\nError occured while parsing: " + tcConfig
163         + "\n\tUnable to locate client log files at: " + clientLogs);
164     return clientLogsDir;
165   }
166
167   private boolean isStdX(String JavaDoc value) {
168     if (value == null) return false;
169     return (value.equals(STDOUT) || value.equals(STDERR));
170   }
171
172   private Server[] getServersElement(TcConfig configBeans) throws IOException JavaDoc, XmlException {
173     Servers servers = configBeans.getServers();
174     if (servers == null) quit("The Terracotta config specified doesn't contain the <servers> element");
175     return servers.getServerArray();
176   }
177
178   private File JavaDoc[] getServerLogsLocation(TcConfig configBeans) throws IOException JavaDoc, XmlException {
179     Server[] servers = getServersElement(configBeans);
180     String JavaDoc[] logs = new String JavaDoc[servers.length];
181     File JavaDoc[] logFiles = new File JavaDoc[servers.length];
182     for (int i = 0; i < servers.length; i++) {
183       logs[i] = servers[i].getLogs();
184       if (isStdX(logs[i])) logs[i] = null;
185       if (logs[i] == null) logs[i] = Server.type.getElementProperty(QName.valueOf("logs")).getDefaultText();
186       logs[i] = ParameterSubstituter.substitute(logs[i]);
187       File JavaDoc serverLogsDir = makeAbsolute(new File JavaDoc(logs[i]));
188       if (!serverLogsDir.exists()) quit("\nError occured while parsing: " + tcConfig
189           + "\n\tUnable to resolve the server log location element to an actual file: " + logs[i]);
190       logFiles[i] = serverLogsDir;
191     }
192     return logFiles;
193   }
194
195   private File JavaDoc[] getServerDataLocation(TcConfig configBeans) throws IOException JavaDoc, XmlException {
196     if (!isFull) return null;
197     Server[] servers = getServersElement(configBeans);
198     String JavaDoc[] serverData = new String JavaDoc[servers.length];
199     File JavaDoc[] dataFiles = new File JavaDoc[servers.length];
200     for (int i = 0; i < servers.length; i++) {
201       serverData[i] = servers[i].getData();
202       if (serverData[i] == null) serverData[i] = Server.type.getElementProperty(QName.valueOf("data")).getDefaultText();
203       serverData[i] = ParameterSubstituter.substitute(serverData[i]);
204       File JavaDoc serverDataDir = makeAbsolute(new File JavaDoc(serverData[i]));
205       if (!serverDataDir.exists()) quit("\nError occured while parsing: " + tcConfig
206           + "\n\tUnable to resolve the server data location element to an actual file: " + serverData[i]);
207       dataFiles[i] = serverDataDir;
208     }
209     return dataFiles;
210   }
211
212   private void createPathArchive() {
213     try {
214       System.out.println("Archiving:\n----------------------------------------");
215       ArchiveBuilder zip = new ZipBuilder(archiveFile, true);
216       zip.putEntry("env-stats", EnvStats.report().getBytes());
217       zip.putTraverseDirectory(tcConfig, tcConfig.getName());
218       zip.finish();
219     } catch (IOException JavaDoc e) {
220       System.out.println("Unexpected error - unable to write Terracotta archive: " + archiveFile);
221       e.printStackTrace();
222       System.exit(1);
223     }
224     System.out.println("\n\nWrote archive to:" + archiveFile);
225   }
226
227   private void createArchive() throws IOException JavaDoc, XmlException {
228     if (tcConfig.isDirectory()) {
229       createPathArchive();
230       return;
231     }
232     TcConfig configBeans = new Loader().parse(tcConfig).getTcConfig();
233     File JavaDoc clientLogsDir = null;
234     File JavaDoc[] serverLogsDir = null;
235     File JavaDoc[] serverDataDir = null;
236     if (isClient) {
237       clientLogsDir = getClientLogsLocation(configBeans);
238     } else {
239       serverLogsDir = getServerLogsLocation(configBeans);
240       serverDataDir = getServerDataLocation(configBeans);
241     }
242     try {
243       ArchiveBuilder zip = new ZipBuilder(archiveFile, true);
244       System.out.println("Archiving:");
245       zip.putEntry(tcConfig.getName(), zip.readFile(tcConfig));
246       if (isClient) {
247         if (clientLogsDir != null) zip.putTraverseDirectory(clientLogsDir, clientLogsDir.getName());
248       } else {
249         for (int i = 0; i < serverLogsDir.length; i++) {
250           if (serverLogsDir[i] != null) zip.putTraverseDirectory(serverLogsDir[i], serverLogsDir[i].getName());
251         }
252         if (serverDataDir != null) {
253           for (int i = 0; i < serverDataDir.length; i++) {
254             zip.putTraverseDirectory(serverDataDir[i], serverDataDir[i].getName());
255           }
256         }
257       }
258       zip.finish();
259     } catch (IOException JavaDoc e) {
260       System.out.println("Unexpected error - unable to write Terracotta archive: " + archiveFile);
261       e.printStackTrace();
262       System.exit(1);
263     }
264     System.out.println("\n\nWrote archive to:" + archiveFile);
265   }
266 }
267
Popular Tags