| 1 16 package org.outerj.daisy.backupTool; 17 18 import java.io.File ; 19 import java.io.FileNotFoundException ; 20 import java.io.PrintWriter ; 21 import java.io.StringWriter ; 22 import java.util.Date ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 import java.util.Properties ; 26 27 import javax.mail.Message ; 28 import javax.mail.Session ; 29 import javax.mail.Transport ; 30 import javax.mail.internet.InternetAddress ; 31 import javax.mail.internet.MimeMessage ; 32 33 import org.apache.commons.cli.CommandLine; 34 import org.apache.commons.cli.CommandLineParser; 35 import org.apache.commons.cli.HelpFormatter; 36 import org.apache.commons.cli.MissingOptionException; 37 import org.apache.commons.cli.Option; 38 import org.apache.commons.cli.OptionGroup; 39 import org.apache.commons.cli.Options; 40 import org.apache.commons.cli.ParseException; 41 import org.apache.commons.cli.PosixParser; 42 import org.w3c.dom.Document ; 43 import org.w3c.dom.Element ; 44 import org.outerj.daisy.util.VersionHelper; 45 46 public class BackupTool { 47 48 private File backupLocation; 49 50 private static String XPATH_JMX_CONF = "/targets/target[@path = '/daisy/jmx/mbeanserver']/configuration/xmlHttpAdaptor"; 51 52 public static void main(String [] args) throws Exception { 53 Options options = createOptions(); 54 CommandLineParser parser = new PosixParser(); 55 Map confMap = new HashMap (); 56 try { 57 CommandLine cmd = parser.parse(options, args); 58 if (cmd.hasOption("h")) 59 printHelp(options); 60 else if (cmd.hasOption('v')) { 61 String versionString = VersionHelper.getVersionString(BackupTool.class.getClassLoader(), 62 "org/outerj/daisy/backupTool/versioninfo.properties"); 63 System.out.println(versionString); 64 } else if (!cmd.hasOption('l') && !(cmd.hasOption('b') || cmd.hasOption('r'))) { 65 System.out.println("The -l and -b or -r options are required."); 66 } else { 67 try { 68 BackupTool tool; 69 File backupLocation = new File (cmd.getOptionValue("l")); 70 71 74 if (cmd.hasOption("a")) 75 confMap.put("additional-entries", new File (cmd.getOptionValue("a"))); 76 77 File datadir = null; 78 79 String datadirPath = cmd.getOptionValue("d"); 80 datadir = new File (datadirPath); 81 confMap.put("datadir", datadir); 82 83 if (cmd.hasOption("b")) { 84 if (!datadir.exists()) { 85 System.out.println("Specified data dir does not exist: " + datadir.getAbsolutePath()); 86 System.exit(1); 87 } 88 89 File myConfig = new File (datadir, "conf" + File.separator + "myconfig.xml"); 90 confMap.put("myconfig", myConfig); 91 92 tool = new BackupTool(confMap, backupLocation); 93 tool.createBackup(); 94 95 } else if (cmd.hasOption("r")) { 96 String backupName = cmd.getOptionValue("r"); 97 tool = new BackupTool(confMap, backupLocation, backupName); 98 tool.restoreBackup(backupName); 99 } else if (cmd.hasOption("R")) { 100 String backupName = cmd.getOptionValue("R"); 101 tool = new BackupTool(confMap, backupLocation, backupName); 102 tool.rehashBackup(backupName); 103 } 104 105 } catch (Exception e) { 106 if (cmd.hasOption("e") && cmd.hasOption("s")) 107 sendExceptionEmail(cmd.getOptionValue("e"), cmd.getOptionValue("f"), cmd.getOptionValue("s"), e); 108 109 e.printStackTrace(); 110 System.exit(1); 111 } 112 } 113 } catch (ParseException e) { 114 if (e instanceof MissingOptionException) 115 System.err.println("The " + e.getMessage() + " option is required."); 116 else 117 e.printStackTrace(); 118 119 printHelp(options); 120 System.exit(1); 121 } 122 } 123 124 public BackupTool(Map confMap, File backupLocation, String backupname) throws Exception { 125 if (!backupLocation.exists()) 126 throw new FileNotFoundException ("The backup directory " + backupLocation.getPath() + " does not exist"); 127 128 this.backupLocation = backupLocation; 129 File backupInstance = new File (backupLocation, backupname); 130 if (!backupInstance.exists()) 131 throw new FileNotFoundException ("The backup at " + backupInstance.getPath() + " could not be found"); 132 133 File confDir = new File (backupInstance, "conftemp"); 134 BackupHelper.unzipToDirectory(new File (backupInstance, "daisy-conf.zip"), confDir); 135 confMap.put("myconfig", new File (confDir, "myconfig.xml")); 136 confMap.put("confdir", confDir); 137 138 init(confMap); 139 BackupHelper.deleteFile(confDir); 140 } 141 142 public BackupTool(Map confMap, File backupLocation) throws Exception { 143 if (!backupLocation.exists()) { 144 if (!backupLocation.mkdirs()) 145 throw new Exception ("Could not create the backup directory " + backupLocation.getAbsolutePath()); 146 } 147 this.backupLocation = backupLocation; 148 init(confMap); 149 } 150 151 private void init(Map confMap) throws Exception { 152 if (confMap.containsKey("myconfig")) { 153 File myConfig = (File )confMap.get("myconfig"); 154 155 Document myConfigDocument = BackupHelper.parseFile(myConfig); 156 Element jmxConf = BackupHelper.getElementFromDom(myConfigDocument, XPATH_JMX_CONF); 157 158 JMXRepositoryLocker locker = new JMXRepositoryLocker(jmxConf.getAttribute("host"), Integer.parseInt(jmxConf.getAttribute("port")), jmxConf 159 .getAttribute("username"), jmxConf.getAttribute("password")); 160 161 BackupManager.setLocker(locker); 162 BackupManager.setBackupLocation(backupLocation); 163 164 File datadir = (File )confMap.get("datadir"); 165 BackupManager.getInstance().registerEntryLoader(new DaisyEntryLoader(myConfig, datadir)); 166 167 File confdir = (File )confMap.get("confdir"); 173 if (confdir == null) confdir = new File (datadir, "conf"); 175 File amqConfFile = new File (confdir, "activemq-conf.xml"); 176 BackupManager.getInstance().registerEntryLoader(new ActiveMQEntryLoader(amqConfFile)); 177 } 178 179 if (confMap.containsKey("openjms")) 180 BackupManager.getInstance().registerEntryLoader(new OpenJMSEntryLoader((File )confMap.get("openjms"))); 181 182 if (confMap.containsKey("additional-entries")) 183 BackupManager.getInstance().registerEntryLoader(new FileListEntryLoader((File )confMap.get("additional-entries"))); 184 } 185 186 public void createBackup() throws Exception { 187 BackupInstance buInstance = BackupManager.getInstance().createBackupInstance(); 188 BackupManager.getInstance().backup(buInstance); 189 } 190 191 public void restoreBackup(String backupName) throws Exception { 192 BackupInstance buInstance = BackupManager.getInstance().loadBackupInstance(backupName); 193 194 System.out.println(); 195 System.out.println("Before restoring a backup, make sure that the repository server"); 196 System.out.println("and the Daisy Wiki are not running."); 197 System.out.println(); 198 199 boolean doRestore = BackupHelper.promptYesNo("Restoring this backup will undo all changes made since " + buInstance.getCreateDate().toString() 200 + "\nDo you wish to restore the backup? [yes|no, default: no]", false); 201 if (doRestore) 202 BackupManager.getInstance().restore(buInstance); 203 } 204 205 public void rehashBackup(String backupName) throws Exception { 206 BackupInstance buInstance = BackupManager.getInstance().loadBackupInstance(backupName); 207 System.out.println("Rehashing backup entries at " + buInstance.getDirectory().getAbsolutePath()); 208 BackupManager.getInstance().rehash(buInstance); 209 System.out.println("Done"); 210 } 211 212 private static void printHelp(Options o) { 213 HelpFormatter help = new HelpFormatter(); 214 help.printHelp("daisy-backup-tool", o, true); 215 } 216 217 private static Options createOptions() { 218 Options options = new Options(); 219 220 Option versionOption = new Option("v", "version", false, "Print version info"); 221 222 Option configOption = new Option("d", "daisy-data-dir", true, "Daisy data directory"); 223 configOption.setRequired(true); 224 configOption.setArgName("daisydata-path"); 225 226 229 Option backupLocationOption = new Option("l", "backuplocation", true, "Location where backups are stored"); 230 backupLocationOption.setArgName("backup-path"); 231 232 Option emailTo = new Option("e", "emailaddress", true, "Where emails will be sent to incase of an exception"); 233 emailTo.setArgName("email-address"); 234 235 Option emailFrom = new Option("f", "fromaddress", true, "Sender address to use for exception emails"); 236 emailFrom.setArgName("from-address"); 237 238 Option smtpServer = new Option("s", "smtp-server", true, "Smtp server"); 239 smtpServer.setArgName("smtp-server"); 240 241 Option additionalEntries = new Option("a", "additional-entries", true, "Path to configuration of additional backup entries"); 242 additionalEntries.setArgName("entry-configuration-file"); 243 244 OptionGroup commandGroup = new OptionGroup(); 245 Option restoreOption = new Option("r", "restore", true, "Restore an existing backup"); 246 restoreOption.setArgName("backup-name"); 247 Option backupOption = new Option("b", "backup", false, "Create a new backup"); 248 Option rehashOption = new Option("R", "rehash", true, "Rehash files from an existing backup"); 249 rehashOption.setArgName("backup-name"); 250 commandGroup.addOption(backupOption); 251 commandGroup.addOption(restoreOption); 252 commandGroup.addOption(rehashOption); 253 commandGroup.addOption(versionOption); 254 commandGroup.addOption( new Option("h", "help", false, "Show this message")); 255 commandGroup.setRequired(true); 256 257 258 options.addOption(configOption); 259 options.addOption(backupLocationOption); 260 options.addOptionGroup(commandGroup); 261 options.addOption(emailTo); 263 options.addOption(emailFrom); 264 options.addOption(smtpServer); 265 options.addOption(additionalEntries); 266 267 return options; 268 } 269 270 private static void sendExceptionEmail(String to, String from, String smtpHost, Exception e) throws Exception { 271 Properties props = new Properties (); 272 props.put("mail.smtp.host", smtpHost); 273 274 MimeMessage msg = new MimeMessage (Session.getInstance(props)); 275 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); 276 msg.setSubject("Daisy Backup Failed"); 277 278 if (from != null){ 279 msg.setFrom(new InternetAddress (from)); 280 } 281 282 StringWriter sw = new StringWriter (); 283 PrintWriter pw = new PrintWriter (sw); 284 e.printStackTrace(pw); 285 String text = "Stacktrace :\n" + sw.toString(); 286 287 msg.setText(text); 288 msg.setSentDate(new Date ()); 289 290 Transport.send(msg); 291 } 292 293 } 294 | Popular Tags |