1 21 22 package org.continuent.sequoia.controller.backup.backupers; 23 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.util.ArrayList ; 27 import java.util.Iterator ; 28 import java.util.regex.Matcher ; 29 import java.util.regex.Pattern ; 30 31 import org.continuent.sequoia.common.exceptions.BackupException; 32 import org.continuent.sequoia.common.log.Trace; 33 import org.continuent.sequoia.controller.backup.Backuper; 34 35 59 public abstract class AbstractPostgreSQLBackuper extends AbstractBackuper 60 { 61 private static final String DEFAULT_POSTGRESQL_PORT = "5432"; 62 private static final String DEFAULT_POSTGRESQL_HOST = "localhost"; 63 64 private static Trace logger = Trace 66 .getLogger(AbstractPostgreSQLBackuper.class 67 .getName()); 68 69 70 static Trace endUserLogger = Trace 71 .getLogger("org.continuent.sequoia.enduser"); 72 73 protected NativeCommandExec nativeCmdExec = new NativeCommandExec(); 75 76 protected static String binDir = null; 78 protected static String encoding = null; 79 protected static boolean useAuthentication = false; 80 protected static String dumpServer = null; 81 protected static String preRestoreScript = null; 82 protected static String postRestoreScript = null; 83 protected static String pgDumpFlags = null; 84 protected static String dumpTimeout = null; 85 protected static String restoreTimeout = null; 86 protected static String splitSize = "1000m"; 87 88 91 public AbstractPostgreSQLBackuper() 92 { 93 } 94 95 98 public String getOptions() 99 { 100 return optionsString; 101 } 102 103 106 public void setOptions(String options) 107 { 108 super.setOptions(options); 109 110 if (optionsMap.containsKey("bindir")) 113 binDir = (String ) optionsMap.get("bindir"); 114 if (optionsMap.containsKey("encoding")) 115 encoding = (String ) optionsMap.get("encoding"); 116 if (optionsMap.containsKey("authentication") 117 && ((String ) optionsMap.get("authentication")).equalsIgnoreCase("true")) 118 useAuthentication = true; 119 if (optionsMap.containsKey("dumpServer")) 120 dumpServer = (String ) optionsMap.get("dumpServer"); 121 if (optionsMap.containsKey("preRestoreScript")) 122 preRestoreScript = (String ) optionsMap.get("preRestoreScript"); 123 if (optionsMap.containsKey("postRestoreScript")) 124 postRestoreScript = (String ) optionsMap.get("postRestoreScript"); 125 if (optionsMap.containsKey("dumpTimeout")) 126 dumpTimeout = (String ) optionsMap.get("dumpTimeout"); 127 if (optionsMap.containsKey("restoreTimeout")) 128 restoreTimeout = (String ) optionsMap.get("restoreTimeout"); 129 if (optionsMap.containsKey("pgDumpFlags")) 130 pgDumpFlags = (String ) optionsMap.get("pgDumpFlags"); 131 if (optionsMap.containsKey("splitSize")) 132 splitSize = (String ) optionsMap.get("splitSize"); 133 134 } 135 136 140 public void deleteDump(String path, String dumpName) throws BackupException 141 { 142 File toRemove = new File (getDumpPhysicalPath(path, dumpName)); 143 if (logger.isDebugEnabled()) 144 logger.debug("Deleting dump " + toRemove); 145 toRemove.delete(); 146 } 147 148 155 protected String getDumpPhysicalPath(String path, String dumpName) 156 { 157 String fullPath = null; 158 159 if (path.endsWith(File.separator)) 160 fullPath = path + dumpName; 161 else 162 fullPath = path + File.separator + dumpName; 163 164 return fullPath; 165 } 166 167 177 protected String makeCommand(String command, PostgreSQLUrlInfo info, 178 String options, String login) 179 { 180 String prefix = binDir != null ? binDir + File.separator : ""; 181 return prefix + command + " " + info.getHostParametersString() + " -U " 182 + login + " " + options + " " + info.dbName; 183 } 184 185 200 protected String [] makeCommandWithAuthentication(String command, 201 PostgreSQLUrlInfo info, String options, String login, String password, 202 boolean isPsql) 203 { 204 StringBuffer cmdBuff = new StringBuffer ("spawn "); 206 207 if (binDir != null) 208 cmdBuff.append(binDir + File.separator); 209 210 cmdBuff.append(command); 211 cmdBuff.append(" "); 212 cmdBuff.append(info.getHostParametersString()); 213 cmdBuff.append(" -U "); 214 cmdBuff.append(login); 215 cmdBuff.append(" "); 216 cmdBuff.append(options); 217 cmdBuff.append(" "); 218 cmdBuff.append(info.dbName); 219 cmdBuff.append("; "); 220 if (isPsql) 222 cmdBuff.append("expect \"Password:\"; "); 223 else 224 cmdBuff.append("expect \"Password for user " + login + ":\"; "); 225 cmdBuff.append("send \""); 226 cmdBuff.append(password); 227 cmdBuff.append("\"; "); 228 cmdBuff.append("send \"\\r\"; "); 229 cmdBuff.append("expect eof;"); 230 231 String [] commands = {"expect", "-c", cmdBuff.toString()}; 232 return commands; 233 } 234 235 245 protected String [] makeSplitCommand(String command, PostgreSQLUrlInfo info, 246 String options, String login) 247 { 248 String prefix = binDir != null ? binDir + File.separator : ""; 249 String cmd = prefix + command + " " + info.dbName + " " 250 + info.getHostParametersString() + " -U " + login + " " + options; 251 String [] cmdArray = {"bash", "-c", cmd}; 252 return cmdArray; 253 } 256 257 277 protected String [] makeExpectDialogueWithAuthentication(String command, 278 PostgreSQLUrlInfo info, String options, String login, String password, 279 int timeout) 280 { 281 String [] cmdBuff = new String [27]; 282 283 if (binDir != null) 284 cmdBuff[0] = new String ("spawn " + binDir + File.separator + command 285 + " " + info.getHostParametersString() + " -U " + login + " -W " 286 + options + " " + info.getDbName()); 287 else 288 cmdBuff[0] = new String ("spawn " + command + " " 289 + info.getHostParametersString() + " -U " + login + " -W " + options 290 + " " + info.getDbName()); 291 cmdBuff[1] = new String ("proc abort {} {"); 292 cmdBuff[2] = new String (" system kill [exp_pid]"); 293 cmdBuff[3] = new String (" exit 1"); 294 cmdBuff[4] = new String ("}"); 295 cmdBuff[5] = new String ("set exitcode 1"); 296 cmdBuff[6] = new String ("expect {"); 297 cmdBuff[7] = new String (" \"Password for user " + login 298 + ":\" { set exitcode 0 }"); 299 cmdBuff[8] = new String (" \"assword:\" { set exitcode 0 }"); 300 cmdBuff[9] = new String (" timeout { abort }"); 301 cmdBuff[10] = new String ("}"); 302 cmdBuff[11] = new String ("send \"" + password + "\""); 303 cmdBuff[12] = new String ("send \"\r\""); 304 cmdBuff[13] = new String ("set timeout " + timeout); 305 cmdBuff[14] = new String ("expect {"); 306 cmdBuff[15] = new String ( 307 " \"ERROR:\" { set exitcode 1; exp_continue -continue_timer }"); 308 cmdBuff[16] = new String ( 309 " \"FATAL:\" { set exitcode 1; exp_continue -continue_timer }"); 310 cmdBuff[17] = new String (" timeout { abort }"); 311 cmdBuff[18] = new String (" eof { if {$exitcode != 0} { abort }}"); 312 cmdBuff[19] = new String ("}"); 313 cmdBuff[20] = new String ("set rc [wait]"); 314 cmdBuff[21] = new String ("set os_error [lindex $rc 2]"); 315 cmdBuff[22] = new String ("set status [lindex $rc 3]"); 316 cmdBuff[23] = new String ("if {$os_error != 0 || $status != 0} {"); 317 cmdBuff[24] = new String (" exit 1"); 318 cmdBuff[25] = new String ("}"); 319 cmdBuff[26] = new String ("exit 0"); 320 return cmdBuff; 321 } 322 323 338 protected String [] makeSplitCommandWithAuthentication(String command, 339 PostgreSQLUrlInfo info, String options, String login, String password, 340 boolean isPsql) 341 { 342 StringBuffer cmdBuff = new StringBuffer ("spawn "); 344 345 if (binDir != null) 346 cmdBuff.append(binDir + File.separator); 347 348 cmdBuff.append(command); 349 cmdBuff.append(" "); 350 cmdBuff.append(info.dbName); cmdBuff.append(" "); cmdBuff.append(info.getHostParametersString()); 353 cmdBuff.append(" -U "); 354 cmdBuff.append(login); 355 cmdBuff.append(" "); 356 cmdBuff.append(options); 357 cmdBuff.append("; "); 360 if (isPsql) 362 cmdBuff.append("expect \"Password:\"; "); 363 else 364 cmdBuff.append("expect \"Password for user " + login + ":\"; "); 365 cmdBuff.append("send \""); 366 cmdBuff.append(password); 367 cmdBuff.append("\"; "); 368 cmdBuff.append("send \"\\r\"; "); 369 cmdBuff.append("expect eof;"); 370 371 String [] commands = {"expect", "-c", "bash", "-c", cmdBuff.toString()}; return commands; 375 } 376 377 389 protected int executeNativeCommand(String [] stdinFeed, String [] commands) 390 throws IOException , InterruptedException 391 { 392 NativeCommandInputSource input = NativeCommandInputSource 393 .createArrayInputSource(stdinFeed); 394 return nativeCmdExec.executeNativeCommand(commands, input, null, 0, 395 getIgnoreStdErrOutput()); 396 } 397 398 407 protected String [] makeExpectCommandReadingStdin() 408 { 409 String [] commands = {"expect", "-"}; 410 return commands; 414 } 415 416 426 protected int executeNativeCommand(String command) throws IOException , 427 InterruptedException 428 { 429 return nativeCmdExec.executeNativeCommand(command, null, null, 0, 430 getIgnoreStdErrOutput()); 431 } 432 433 451 protected int executeNativeCommand(String [] commands) throws IOException , 452 InterruptedException 453 { 454 return nativeCmdExec.executeNativeCommand(commands, null, null, 0, 455 getIgnoreStdErrOutput()); 456 } 457 458 466 protected boolean safelyExecNativeCommand(String cmd, String [] inputArray, 467 int timeout) 468 { 469 NativeCommandInputSource input = NativeCommandInputSource 470 .createArrayInputSource(inputArray); 471 return nativeCmdExec.safelyExecNativeCommand(cmd, input, null, timeout, 472 getIgnoreStdErrOutput()); 473 } 474 475 483 protected boolean safelyExecNativeCommand(String [] cmds, String [] inputArray, 484 int timeout) 485 { 486 NativeCommandInputSource input = NativeCommandInputSource 487 .createArrayInputSource(inputArray); 488 return nativeCmdExec.safelyExecNativeCommand(cmds, input, null, timeout, 489 getIgnoreStdErrOutput()); 490 } 491 492 495 protected void printErrors() 496 { 497 ArrayList errors = nativeCmdExec.getStderr(); 498 Iterator it = errors.iterator(); 499 while (it.hasNext()) 500 { 501 String msg = (String ) it.next(); 502 logger.info(msg); 503 endUserLogger.error(msg); 504 } 505 } 506 507 510 protected void printOutput() 511 { 512 ArrayList errors = nativeCmdExec.getStderr(); 513 Iterator it = errors.iterator(); 514 while (it.hasNext()) 515 { 516 String msg = (String ) it.next(); 517 logger.info(msg); 518 endUserLogger.error(msg); 519 } 520 } 521 522 525 protected class PostgreSQLUrlInfo 526 { 527 private boolean isLocal; 528 private String host; 529 private String port; 530 private String dbName; 531 532 private Pattern pattern = Pattern 536 .compile("jdbc:postgresql:((//([a-zA-Z0-9_\\-.]+|\\[[a-fA-F0-9:]+])((:(\\d+))|))/|)([^\\s?]*).*$"); 537 Matcher matcher; 538 539 546 public PostgreSQLUrlInfo(String url) 547 { 548 matcher = pattern.matcher(url); 549 550 if (matcher.matches()) 551 { 552 if (matcher.group(3) != null) 553 host = matcher.group(3); 554 else 555 host = DEFAULT_POSTGRESQL_HOST; 556 557 if (matcher.group(6) != null) 558 port = matcher.group(6); 559 else 560 port = DEFAULT_POSTGRESQL_PORT; 561 562 dbName = matcher.group(7); 563 } 564 } 565 566 572 public String getHostParametersString() 573 { 574 if (isLocal) 575 { 576 return ""; 577 } 578 else 579 { 580 return "-h " + host + " -p " + port; 581 } 582 } 583 584 589 public String getDbName() 590 { 591 return dbName; 592 } 593 594 599 public String getHost() 600 { 601 return host; 602 } 603 604 609 public String getPort() 610 { 611 return port; 612 } 613 614 621 public boolean isLocal() 622 { 623 return isLocal; 624 } 625 626 } 627 } 628 | Popular Tags |