001/* 002 * #%L 003 * Netarchivesuite - deploy 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.deploy; 024 025import java.io.File; 026import java.io.IOException; 027import java.io.PrintWriter; 028import java.util.ArrayList; 029import java.util.List; 030 031import org.dom4j.Attribute; 032import org.dom4j.Element; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036import dk.netarkivet.common.exceptions.ArgumentNotValid; 037import dk.netarkivet.common.exceptions.IOFailure; 038import dk.netarkivet.common.exceptions.IllegalState; 039import dk.netarkivet.common.utils.FileUtils; 040 041/** 042 * Machine defines an abstract representation of a physical computer at a physical location. The actual instances are 043 * depending on the operation system: LinuxMachine and WindowsMachine. All non-OS specific methods are implemented this 044 * machine class. 045 */ 046public abstract class Machine { 047 048 /** the log, for logging stuff instead of displaying them directly. */ 049 protected static final Logger log = LoggerFactory.getLogger(Machine.class); 050 /** The root-branch for this machine in the XML tree. */ 051 protected Element machineRoot; 052 /** The settings, inherited from parent and overwritten. */ 053 protected XmlStructure settings; 054 /** The machine parameters. */ 055 protected Parameters machineParameters; 056 /** The list of the application on this machine. */ 057 protected List<Application> applications; 058 /** The name of this machine. */ 059 protected String hostname; 060 /** The operating system on this machine: 'windows' or 'linux'. */ 061 protected String operatingSystem; 062 /** The extension on the script files (specified by operating system). */ 063 protected String scriptExtension; 064 /** The name of the NetarchiveSuite.zip file. */ 065 protected String netarchiveSuiteFileName; 066 /** The inherited SLF4J config file. */ 067 protected File inheritedSlf4jConfigFile; 068 /** The inherited security.policy file. */ 069 protected File inheritedSecurityPolicyFile; 070 /** The inherited database file name. */ 071 protected File databaseFile; 072 /** The inherited archive database file name. */ 073 protected File arcDatabaseFile; 074 /** The directory for this machine. */ 075 protected File machineDirectory; 076 /** Whether the temp dir should be cleaned. */ 077 protected boolean resetTempDir; 078 /** The folder containing the external jar library files. */ 079 protected File jarFolder; 080 /** The encoding to use when writing files. */ 081 protected String targetEncoding; 082 083 /** 084 * A machine is referring to an actual computer at a physical location, which can have independent applications from 085 * the other machines at the same location. 086 * 087 * @param subTreeRoot The root of this instance in the XML document. 088 * @param parentSettings The setting inherited by the parent. 089 * @param param The machine parameters inherited by the parent. 090 * @param netarchiveSuiteSource The name of the NetarchiveSuite package file. 091 * @param securityPolicy The security policy file. 092 * @param dbFileName The name of the database file. 093 * @param archiveDbFileName The name of the archive database file. 094 * @param resetDir Whether the temporary directory should be reset. 095 * @param externalJarFolder The folder containing the external jar library files. 096 * @throws ArgumentNotValid If one of the following arguments are null: subTreeRoot, parentSettings, param, 097 * netarchiveSuiteSource, logProp, securityPolicy. 098 */ 099 public Machine(Element subTreeRoot, XmlStructure parentSettings, Parameters param, String netarchiveSuiteSource, 100 File slf4JConfig, File securityPolicy, File dbFileName, File archiveDbFileName, 101 boolean resetDir, File externalJarFolder) throws ArgumentNotValid { 102 ArgumentNotValid.checkNotNull(subTreeRoot, "Element subTreeRoot"); 103 ArgumentNotValid.checkNotNull(parentSettings, "XmlStructure parentSettings"); 104 ArgumentNotValid.checkNotNull(param, "Parameters param"); 105 ArgumentNotValid.checkNotNull(netarchiveSuiteSource, "String netarchiveSuiteSource"); 106 ArgumentNotValid.checkNotNull(slf4JConfig, "File slf4JConfig"); 107 ArgumentNotValid.checkNotNull(securityPolicy, "File securityPolicy"); 108 109 settings = new XmlStructure(parentSettings.getRoot()); 110 machineRoot = subTreeRoot; 111 machineParameters = new Parameters(param); 112 netarchiveSuiteFileName = netarchiveSuiteSource; 113 inheritedSlf4jConfigFile = slf4JConfig; 114 inheritedSecurityPolicyFile = securityPolicy; 115 databaseFile = dbFileName; 116 arcDatabaseFile = archiveDbFileName; 117 resetTempDir = resetDir; 118 jarFolder = externalJarFolder; 119 120 // Retrieve machine encoding 121 targetEncoding = machineRoot.attributeValue(Constants.MACHINE_ENCODING_ATTRIBUTE); 122 String msgTail = ""; 123 if (targetEncoding == null || targetEncoding.isEmpty()) { 124 targetEncoding = Constants.MACHINE_ENCODING_DEFAULT; 125 msgTail = " (defaulted)"; 126 } 127 System.out.println("Machine '" + machineRoot.attributeValue(Constants.MACHINE_NAME_ATTRIBUTE) 128 + "' configured with encoding '" + targetEncoding + "'" + msgTail); 129 130 // retrieve the specific settings for this instance 131 Element tmpSet = machineRoot.element(Constants.COMPLETE_SETTINGS_BRANCH); 132 // Generate the specific settings by combining the general settings 133 // and the specific, (only if this instance has specific settings) 134 if (tmpSet != null) { 135 settings.overWrite(tmpSet); 136 } 137 138 // check if new machine parameters 139 machineParameters.newParameters(machineRoot); 140 // Retrieve the variables for this instance. 141 extractVariables(); 142 // generate the machines on this instance 143 extractApplications(); 144 } 145 146 /** 147 * Extract the local variables from the root. Currently, this is the name and the operating system. 148 */ 149 private void extractVariables() { 150 // retrieve name 151 Attribute at = machineRoot.attribute(Constants.MACHINE_NAME_ATTRIBUTE); 152 if (at != null) { 153 hostname = at.getText().trim(); 154 } else { 155 throw new IllegalState("A Machine instance has no name!"); 156 } 157 } 158 159 /** 160 * Extracts the XML for the applications from the root, creates the applications and puts them into the list. 161 */ 162 @SuppressWarnings("unchecked") 163 private void extractApplications() { 164 applications = new ArrayList<Application>(); 165 List<Element> le = machineRoot.elements(Constants.DEPLOY_APPLICATION_NAME); 166 for (Element e : le) { 167 applications.add(new Application(e, settings, machineParameters, targetEncoding)); 168 } 169 } 170 171 /** 172 * Create the directory for the specific configurations of this machine and call the functions for creating all the 173 * scripts in this directory. 174 * 175 * @param parentDirectory The directory where to write the files. 176 * @throws ArgumentNotValid If the parenteDirectory is null. 177 */ 178 public void write(File parentDirectory) throws ArgumentNotValid { 179 ArgumentNotValid.checkNotNull(parentDirectory, "File parentDirectory"); 180 181 // create the directory for this machine 182 machineDirectory = new File(parentDirectory, hostname); 183 FileUtils.createDir(machineDirectory); 184 185 // 186 // create the content in the directory 187 // 188 189 // Create kill scripts 190 createApplicationKillScripts(machineDirectory); 191 createOSLocalKillAllScript(machineDirectory); 192 createHarvestDatabaseKillScript(machineDirectory); 193 createArchiveDatabaseKillScript(machineDirectory); 194 // create start scripts 195 createApplicationStartScripts(machineDirectory); 196 createOSLocalStartAllScript(machineDirectory); 197 createHarvestDatabaseStartScript(machineDirectory); 198 createArchiveDatabaseStartScript(machineDirectory); 199 createHarvestDatabaseUpdateScript(machineDirectory); 200 // create restart script 201 createRestartScript(machineDirectory); 202 // copy the security policy file 203 createSecurityPolicyFile(machineDirectory); 204 // create the SLF4J property files 205 createSlf4jConfigFiles(machineDirectory); 206 // create the jmx remote files 207 createJmxRemotePasswordFile(machineDirectory); 208 createJmxRemoteAccessFile(machineDirectory); 209 // create the installCreateDir script 210 createInstallDirScript(parentDirectory); 211 212 // write the settings for all application at this machine 213 for (Application app : applications) { 214 app.createSettingsFile(machineDirectory); 215 } 216 } 217 218 /** 219 * Make the script for killing this machine. This is put into the entire kill all script for the physical location. 220 * 221 * @return The script to kill this machine. 222 */ 223 public String writeToGlobalKillScript() { 224 StringBuilder res = new StringBuilder(); 225 res.append(ScriptConstants.writeKillMachineHeader(machineUserLogin())); 226 // write the operating system dependent part of the kill script 227 res.append(osKillScript()); 228 return res.toString(); 229 } 230 231 /** 232 * Make the script for installing this machine. This is put into the entire install script for the physical 233 * location. 234 * 235 * @return The script to make the installation on this machine 236 */ 237 public String writeToGlobalInstallScript() { 238 StringBuilder res = new StringBuilder(); 239 res.append(ScriptConstants.writeInstallMachineHeader(machineUserLogin())); 240 // write the operating system dependent part of the install script 241 res.append(osInstallScript()); 242 return res.toString(); 243 } 244 245 /** 246 * Make the script for starting this machine. This is put into the entire startall script for the physical location. 247 * 248 * @return The script to start this machine. 249 */ 250 public String writeToGlobalStartScript() { 251 StringBuilder res = new StringBuilder(); 252 res.append(ScriptConstants.writeStartMachineHeader(machineUserLogin())); 253 // write the operating system dependent part of the start script 254 res.append(osStartScript()); 255 return res.toString(); 256 } 257 258 /** 259 * Copy inherited securityPolicyFile to local directory. 260 * 261 * @param directory The local directory for this machine. 262 * @throws IOFailure If an error occurred during the creation of the security policy file. 263 */ 264 protected void createSecurityPolicyFile(File directory) throws IOFailure { 265 // make file 266 File secPolFile = new File(directory, Constants.SECURITY_POLICY_FILE_NAME); 267 try { 268 // init writer 269 PrintWriter secPrinter = new PrintWriter(secPolFile, getTargetEncoding()); 270 try { 271 // read the inherited security policy file. 272 String prop = FileUtils.readFile(inheritedSecurityPolicyFile); 273 274 // change the jmx monitor role (if defined in settings) 275 String monitorRole = settings.getLeafValue(Constants.SETTINGS_MONITOR_JMX_NAME_LEAF); 276 if (monitorRole != null) { 277 prop = prop.replace(Constants.SECURITY_JMX_PRINCIPAL_NAME_TAG, monitorRole); 278 } 279 280 // Change the common temp dir (if defined in settings) 281 String ctd = settings.getLeafValue(Constants.SETTINGS_TEMPDIR_LEAF); 282 if (ctd != null) { 283 prop = prop.replace(Constants.SECURITY_COMMON_TEMP_DIR_TAG, ctd); 284 } 285 286 // write to file. 287 secPrinter.write(prop); 288 289 // initialise list of directories to add 290 List<String> dirs = new ArrayList<String>(); 291 292 // get all directories to add and put them into the list 293 for (Application app : applications) { 294 // get archive.fileDir directory. 295 String[] tmpDirs = app.getSettingsValues(Constants.SETTINGS_BITARCHIVE_BASEFILEDIR_LEAF); 296 if (tmpDirs != null && tmpDirs.length > 0) { 297 for (String st : tmpDirs) { 298 dirs.add(st); 299 } 300 } 301 } 302 303 // append file directories 304 if (!dirs.isEmpty()) { 305 secPrinter.write("grant {" + "\n"); 306 for (String dir : dirs) { 307 secPrinter.write(ScriptConstants 308 .writeSecurityPolicyDirPermission(changeFileDirPathForSecurity(dir))); 309 } 310 secPrinter.write("};"); 311 } 312 } finally { 313 secPrinter.close(); 314 } 315 } catch (IOException e) { 316 log.warn("IOException while creating security policy file: ", e); 317 throw new IOFailure("Cannot create security policy file.", e); 318 } 319 } 320 321 /** 322 * Creates a the SLF4J config file for every application. This is done by taking the inherited log file and changing 323 * "APPID" in the file into the identification of the application. 324 * 325 * @param directory The local directory for this machine 326 * @throws IOFailure If an error occurred during the creationg of the log property file. 327 */ 328 protected void createSlf4jConfigFiles(File directory) throws IOFailure { 329 // make config file for every application 330 for (Application app : applications) { 331 // make file 332 File logProp = new File(directory, Constants.SLF4J_CONFIG_APPLICATION_PREFIX + app.getIdentification() 333 + Constants.SLF4J_CONFIG_APPLICATION_SUFFIX); 334 try { 335 // init writer 336 PrintWriter logPrinter = new PrintWriter(logProp, getTargetEncoding()); 337 338 try { 339 // read the inherited log property file. 340 String prop = FileUtils.readFile(inheritedSlf4jConfigFile); 341 342 // append stuff! 343 prop = prop.replace(Constants.LOG_PROPERTY_APPLICATION_ID_TAG, app.getIdentification()); 344 prop = modifyLogProperties(prop); 345 // write to file. 346 logPrinter.write(prop); 347 } finally { 348 logPrinter.close(); 349 } 350 } catch (IOException e) { 351 log.warn("IOException while creating SLF4J config file:", e); 352 throw new IOFailure("Cannot create SLF4J config file.", e); 353 } 354 } 355 } 356 357 /** 358 * Make any OS-specific modifications to logging properties. The default makes no modifications, but this can be 359 * overridden in subclasses. 360 * 361 * @param logProperties the contents of the logging properties file. 362 * @return the contents of the logging properties file with any desired modifications. 363 */ 364 protected String modifyLogProperties(String logProperties) { 365 return logProperties; 366 } 367 368 /** 369 * Creates the jmxremote.password file, based on the settings. 370 * 371 * @param directory The local directory for this machine 372 * @throws IOFailure If an error occurred during the creation of the jmx remote password file. 373 */ 374 protected void createJmxRemotePasswordFile(File directory) throws IOFailure { 375 // make file 376 File jmxFile = new File(directory, Constants.JMX_PASSWORD_FILE_NAME); 377 try { 378 // init writer 379 PrintWriter jw = new PrintWriter(jmxFile, getTargetEncoding()); 380 try { 381 // Write the header of the jmxremote.password file. 382 jw.print(ScriptConstants.JMXREMOTE_PASSWORD_HEADER); 383 384 // Get the username and password for monitor and heritrix. 385 StringBuilder logins = new StringBuilder(); 386 387 // Append the jmx logins for monitor and heritrix. 388 logins.append(getMonitorLogin()); 389 logins.append(getHeritrixLogin()); 390 391 jw.print(logins.toString()); 392 } finally { 393 jw.close(); 394 } 395 } catch (IOException e) { 396 log.trace("IOException while creating jmxremote.password:", e); 397 throw new IOFailure("Cannot create jmxremote.password.", e); 398 } 399 } 400 401 /** 402 * Creates the jmxremote.password file, based on the settings. 403 * 404 * @param directory The local directory for this machine 405 * @throws IOFailure If an error occurred during the creation of the jmx remote access file. 406 */ 407 protected void createJmxRemoteAccessFile(File directory) throws IOFailure { 408 // make file 409 File jmxFile = new File(directory, Constants.JMX_ACCESS_FILE_NAME); 410 try { 411 // init writer 412 PrintWriter jw = new PrintWriter(jmxFile, getTargetEncoding()); 413 try { 414 // Write the header of the jmxremote.password file. 415 jw.print(ScriptConstants.JMXREMOTE_ACCESS_HEADER); 416 417 // Get the username and password for monitor and heritrix. 418 StringBuilder logins = new StringBuilder(); 419 420 // Append the jmx logins for monitor and heritrix. 421 logins.append(getMonitorUsername()); 422 logins.append(getHeritrixUsername()); 423 424 jw.print(logins.toString()); 425 } finally { 426 jw.close(); 427 } 428 } catch (IOException e) { 429 log.trace("IOException while creating jmxremote.access file:", e); 430 throw new IOFailure("Cannot create jmxremote.access file.", e); 431 } 432 } 433 434 /** 435 * For finding the jmxUsernames and jmxPasswords under the monitor branch in the settings. Goes through all 436 * applications, which all must have the same username and the same passwords. 437 * 438 * @return The string to add to the jmxremote.password file. 439 * @throws IllegalState If there is a different amount of usernames and passwords, or if two application has 440 * different values for their username or passwords (applications without values are ignored). 441 */ 442 protected String getMonitorLogin() throws IllegalState { 443 StringBuilder res = new StringBuilder(); 444 // initialise list of usernames and passwords to add 445 List<String> usernames = new ArrayList<String>(); 446 List<String> passwords = new ArrayList<String>(); 447 String[] tmpVals; 448 449 // get values from applications and put them into the lists 450 for (Application app : applications) { 451 // get monitor.jmxUsername 452 tmpVals = app.getSettingsValues(Constants.SETTINGS_MONITOR_JMX_NAME_LEAF); 453 if (tmpVals != null && tmpVals.length > 0) { 454 for (String st : tmpVals) { 455 usernames.add(st); 456 } 457 } 458 // get monitor.jmxPassword 459 tmpVals = app.getSettingsValues(Constants.SETTINGS_MONITOR_JMX_PASSWORD_LEAF); 460 if (tmpVals != null && tmpVals.length > 0) { 461 for (String st : tmpVals) { 462 passwords.add(st); 463 } 464 } 465 } 466 467 // if different amount of usernames and passwords => DIE 468 if (usernames.size() != passwords.size()) { 469 String msg = "Different amount of usernames and passwords in monitor under applications on machine: '" 470 + hostname + "'"; 471 log.warn(msg); 472 throw new IllegalState(msg); 473 } 474 475 // warn if no usernames for monitor. 476 if (usernames.size() == 0) { 477 log.warn("No usernames or passwords for monitor on machine: '{}'", hostname); 478 } 479 480 // check if the usernames and passwords are the same. 481 for (int i = 1; i < usernames.size(); i++) { 482 if (!usernames.get(0).equals(usernames.get(i)) || !passwords.get(0).equals(passwords.get(i))) { 483 String msg = "Different usernames or passwords under monitor on the same machine: '" + hostname + "'"; 484 log.warn(msg); 485 throw new IllegalState(msg); 486 } 487 } 488 489 // make the resulting string 490 if (usernames.size() > 0) { 491 res.append(usernames.get(0)); 492 res.append(Constants.SPACE); 493 res.append(passwords.get(0)); 494 res.append(Constants.NEWLINE); 495 } 496 return res.toString(); 497 } 498 499 /** 500 * For retrieving the monitor username for the jmxremote.access file. This will have the rights 'readonly'. 501 * 502 * @return The string for the jmxremote.access file for allowing the monitor user to readonly. 503 * @throws IllegalState If different applications on the machine have different user names. 504 */ 505 protected String getMonitorUsername() throws IllegalState { 506 StringBuilder res = new StringBuilder(); 507 // initialise list of usernames and passwords to add 508 List<String> usernames = new ArrayList<String>(); 509 String[] tmpVals; 510 511 // get values from applications and put them into the lists 512 for (Application app : applications) { 513 // get monitor.jmxUsername 514 tmpVals = app.getSettingsValues(Constants.SETTINGS_MONITOR_JMX_NAME_LEAF); 515 if (tmpVals != null && tmpVals.length > 0) { 516 for (String st : tmpVals) { 517 usernames.add(st); 518 } 519 } 520 } 521 522 // check if the usernames and passwords are the same. 523 for (int i = 1; i < usernames.size(); i++) { 524 if (!usernames.get(0).equals(usernames.get(i))) { 525 String msg = "Different usernames for the monitor on the same machine: '" + hostname + "'"; 526 log.warn(msg); 527 throw new IllegalState(msg); 528 } 529 } 530 531 // make the resulting string 532 if (usernames.size() > 0) { 533 res.append(usernames.get(0)); 534 res.append(Constants.SPACE); 535 res.append(ScriptConstants.JMXREMOTE_MONITOR_PRIVILEGES); 536 res.append(Constants.NEWLINE); 537 } 538 return res.toString(); 539 } 540 541 /** 542 * For finding the jmxUsernames and jmxPasswords under the harvest.harvesting.heritrix branch under in the settings. 543 * Goes through all applications, which all must have the same username and the same passwords. 544 * 545 * @return The string to add to the jmxremote.password file. 546 * @throws IllegalState If there is a different amount of usernames and passwords, or if two application has 547 * different values for their username or passwords (applications without values are ignored). 548 */ 549 protected String getHeritrixLogin() throws IllegalState { 550 StringBuilder res = new StringBuilder(); 551 // initialise list of usernames and passwords to add 552 List<String> usernames = new ArrayList<String>(); 553 List<String> passwords = new ArrayList<String>(); 554 String[] tmpVals; 555 556 // get values from applications and put them into the lists 557 for (Application app : applications) { 558 // get heritrix.jmxUsername 559 tmpVals = app.getSettingsValues(Constants.SETTINGS_HERITRIX_JMX_USERNAME_LEAF); 560 if (tmpVals != null && tmpVals.length > 0) { 561 for (String st : tmpVals) { 562 usernames.add(st); 563 } 564 } 565 // get heritrix.jmxPassword 566 tmpVals = app.getSettingsValues(Constants.SETTINGS_HERITRIX_JMX_PASSWORD_LEAF); 567 if (tmpVals != null && tmpVals.length > 0) { 568 for (String st : tmpVals) { 569 passwords.add(st); 570 } 571 } 572 } 573 574 // if different amount of usernames and passwords. DIE 575 if (usernames.size() != passwords.size()) { 576 String msg = "Different amount of usernames and passwords in heritrix under applications on machine: '" 577 + hostname + "'"; 578 log.warn(msg); 579 throw new IllegalState(msg); 580 } 581 582 // if no usernames, and thus no passwords, finish! 583 if (usernames.size() == 0) { 584 return ""; 585 } 586 587 // check if the usernames and passwords are the same. 588 for (int i = 1; i < usernames.size(); i++) { 589 if (!usernames.get(0).equals(usernames.get(i)) || !passwords.get(0).equals(passwords.get(i))) { 590 String msg = "Different usernames or passwords " + "under heritrix on machine: '" + hostname + "'"; 591 log.warn(msg); 592 throw new IllegalState(msg); 593 } 594 } 595 596 // make the resulting string 597 if (usernames.size() > 0) { 598 res.append(usernames.get(0)); 599 res.append(Constants.SPACE); 600 res.append(passwords.get(0)); 601 res.append(Constants.NEWLINE); 602 } 603 return res.toString(); 604 } 605 606 /** 607 * For retrieving the Heritrix username for the jmxremote.access file. This will have the rights 'readwrite'. 608 * 609 * @return The string for the jmxremote.access file for allowing the heritrix user to readonly. 610 */ 611 protected String getHeritrixUsername() { 612 StringBuilder res = new StringBuilder(); 613 // initialise list of usernames and passwords to add 614 List<String> usernames = new ArrayList<String>(); 615 String[] tmpVals; 616 617 // get values from applications and put them into the lists 618 for (Application app : applications) { 619 // get heritrix.jmxUsername 620 tmpVals = app.getSettingsValues(Constants.SETTINGS_HERITRIX_JMX_USERNAME_LEAF); 621 if (tmpVals != null && tmpVals.length > 0) { 622 for (String st : tmpVals) { 623 usernames.add(st); 624 } 625 } 626 } 627 628 // check if the usernames and passwords are the same. 629 for (int i = 1; i < usernames.size(); i++) { 630 if (!usernames.get(0).equals(usernames.get(i))) { 631 String msg = "Different usernames for Heritrix on the same machine: '" + hostname + "'"; 632 log.warn(msg); 633 throw new IllegalState(msg); 634 } 635 } 636 637 // make the resulting string 638 if (usernames.size() > 0) { 639 res.append(usernames.get(0)); 640 res.append(Constants.SPACE); 641 res.append(ScriptConstants.JMXREMOTE_HERITRIX_PRIVILEGES); 642 res.append(Constants.NEWLINE); 643 } 644 return res.toString(); 645 } 646 647 /** 648 * The string for accessing this machine through SSH. 649 * 650 * @return The access through SSH to the machine 651 */ 652 protected String machineUserLogin() { 653 return machineParameters.getMachineUserName().getStringValue().trim() + Constants.AT + hostname; 654 } 655 656 /** 657 * For retrieving the environment name variable. 658 * 659 * @return The environment name. 660 */ 661 protected String getEnvironmentName() { 662 return settings.getSubChildValue(Constants.SETTINGS_ENVIRONMENT_NAME_LEAF); 663 } 664 665 /** 666 * Creates the kill scripts for all the applications. 667 * 668 * @param directory The directory for this machine (use global variable?). 669 */ 670 protected abstract void createApplicationKillScripts(File directory); 671 672 /** 673 * Creates the start scripts for all the applications. 674 * 675 * @param directory The directory for this machine (use global variable?). 676 */ 677 protected abstract void createApplicationStartScripts(File directory); 678 679 /** 680 * This function creates the script to start all applications on this machine. The scripts calls all the start 681 * script for each application. 682 * 683 * @param directory The directory for this machine (use global variable?). 684 */ 685 protected abstract void createOSLocalStartAllScript(File directory); 686 687 /** 688 * This function creates the script to kill all applications on this machine. The scripts calls all the kill script 689 * for each application. 690 * 691 * @param directory The directory for this machine (use global variable?). 692 */ 693 protected abstract void createOSLocalKillAllScript(File directory); 694 695 /** 696 * The operation system specific path to the installation directory. 697 * 698 * @return Install path. 699 */ 700 protected abstract String getInstallDirPath(); 701 702 /** 703 * The operation system specific path to the conf directory. 704 * 705 * @return Conf path. 706 */ 707 protected abstract String getConfDirPath(); 708 709 /** 710 * The operation system specific path to the lib directory. 711 * 712 * @return Lib path. 713 */ 714 protected abstract String getLibDirPath(); 715 716 /** 717 * Creates the operation system specific killing script for this machine. 718 * 719 * @return Operation system specific part of the killscript. 720 */ 721 protected abstract String osKillScript(); 722 723 /** 724 * Creates the operation system specific installation script for this machine. 725 * 726 * @return Operation system specific part of the installscript. 727 */ 728 protected abstract String osInstallScript(); 729 730 /** 731 * Creates the specified directories in the deploy-configuration file. 732 * 733 * @return The script for creating the directories. 734 */ 735 protected abstract String osInstallScriptCreateDir(); 736 737 /** 738 * Creates the operation system specific starting script for this machine. 739 * 740 * @return Operation system specific part of the startscript. 741 */ 742 protected abstract String osStartScript(); 743 744 /** 745 * Makes all the class paths into the operation system specific syntax, and puts them into a string where they are 746 * separated by the operation system specific separator (':' for linux, ';' for windows). 747 * 748 * @param app The application which has the class paths. 749 * @return The class paths in operation system specific syntax. 750 */ 751 protected abstract String osGetClassPath(Application app); 752 753 /** 754 * Checks if a specific directory for the database is given in the settings, and thus if the database should be 755 * installed on this machine. 756 * <p> 757 * If no specific database is given as deploy argument (databaseFileName = null) then use the standard database 758 * extracted from NetarchiveSuite.zip. Else send the given new database to the standard database location. 759 * <p> 760 * Extract the database in the standard database location to the specified database directory. 761 * 762 * @return The script for installing the database (if needed). 763 */ 764 protected abstract String osInstallDatabase(); 765 766 /** 767 * Checks if a specific directory for the archive database is given in the settings, and thus if the archive 768 * database should be installed on this machine. 769 * <p> 770 * If not specific database is given (adminDatabaseFileName = null) then use the default in the NetarchiveSuite.zip 771 * package. Else send the new archive database to the standard database location, and extract it to the given 772 * location. 773 * 774 * @return The script for installing the archive database (if needed). 775 */ 776 protected abstract String osInstallArchiveDatabase(); 777 778 /** 779 * This function makes the part of the install script for installing the external jar files from within the 780 * jarFolder. If the jarFolder is null, then no action will be performed. 781 * 782 * @return The script for installing the external jar files (if needed). 783 */ 784 protected abstract String osInstallExternalJarFiles(); 785 786 /** 787 * This functions makes the script for creating the new directories. 788 * <p> 789 * Linux creates directories directly through ssh. Windows creates an install a script file for installing the 790 * directories, which has to be sent to the machine, then executed and finally deleted. 791 * 792 * @param dir The name of the directory to create. 793 * @param clean Whether the directory should be cleaned\reset. 794 * @return The lines of code for creating the directories. 795 * @see #createInstallDirScript(File) 796 */ 797 protected abstract String scriptCreateDir(String dir, boolean clean); 798 799 /** 800 * Creates the script for creating the application specified directories. Also creates the directories along the 801 * path to the directories. 802 * 803 * @return The script for creating the application specified directories. 804 */ 805 protected abstract String getAppDirectories(); 806 807 /** 808 * This method does the following: Retrieves the path to the jmxremote.access and jmxremote.password files. Moves 809 * these files, if they are different from standard. Makes the jmxremote.access and jmxremote.password files 810 * readonly. 811 * 812 * @return The commands for handling the jmxremote files. 813 */ 814 protected abstract String getJMXremoteFilesCommand(); 815 816 /** 817 * Function to create the script which installs the new directories. This is only used for windows machines! 818 * 819 * @param dir The directory to put the file 820 */ 821 protected abstract void createInstallDirScript(File dir); 822 823 /** 824 * Creates a script for restating all the applications on a given machine. 825 * 826 * @param dir The directory where the script will be placed. 827 */ 828 protected abstract void createRestartScript(File dir); 829 830 /** 831 * Creates a script for starting the archive database on a given machine. This is only created if the 832 * <globalArchiveDatabaseDir> parameter is defined on the machine level. 833 * 834 * @param dir The directory where the script will be placed. 835 */ 836 protected abstract void createArchiveDatabaseStartScript(File dir); 837 838 /** 839 * Creates a script for killing the archive database on a given machine. This is only created if the 840 * <globalArchiveDatabaseDir> parameter is defined on the machine level. 841 * 842 * @param dir The directory where the script will be placed. 843 */ 844 protected abstract void createArchiveDatabaseKillScript(File dir); 845 846 /** 847 * Creates a script for starting the harvest database on a given machine. This is only created if the 848 * <deployHarvestDatabaseDir> parameter is defined on the machine level. 849 * 850 * @param dir The directory where the script will be placed. 851 */ 852 protected abstract void createHarvestDatabaseStartScript(File dir); 853 854 /** 855 * Creates a script for killing the harvest database on a given machine. This is only created if the 856 * <globalHarvestDatabaseDir> parameter is defined on the machine level. 857 * 858 * @param dir The directory where the script will be placed. 859 */ 860 protected abstract void createHarvestDatabaseKillScript(File dir); 861 862 /** 863 * Changes the file directory path to the format used in the security policy. 864 * 865 * @param path The current path. 866 * @return The formatted path. 867 */ 868 protected abstract String changeFileDirPathForSecurity(String path); 869 870 /** 871 * create a harvestDatabaseUpdatescript in the given machineDirectory. 872 * 873 * @param machineDirectory a given MachineDirectory. 874 */ 875 protected abstract void createHarvestDatabaseUpdateScript(File machineDirectory); 876 877 protected String getTargetEncoding() { 878 return targetEncoding; 879 } 880 881}