001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2008-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS. 026 */ 027package org.opends.server.types; 028 029import static org.opends.messages.ConfigMessages.*; 030import static org.opends.messages.CoreMessages.*; 031import static org.opends.server.config.ConfigConstants.*; 032import static org.opends.server.util.ServerConstants.*; 033 034import java.io.File; 035import java.io.IOException; 036import java.util.Enumeration; 037import java.util.HashMap; 038import java.util.Map; 039import java.util.Properties; 040 041import org.forgerock.i18n.slf4j.LocalizedLogger; 042import org.opends.quicksetup.util.Utils; 043import org.opends.server.api.ConfigHandler; 044import org.opends.server.core.DirectoryServer; 045import org.opends.server.extensions.ConfigFileHandler; 046 047/** 048 * This class provides a set of properties that may control various 049 * aspects of the server environment. Note that these properties may 050 * only be altered before the Directory Server is started. Any 051 * attempt to change an environment configuration property while the 052 * server is running will be rejected. 053 */ 054@org.opends.server.types.PublicAPI( 055 stability=org.opends.server.types.StabilityLevel.VOLATILE, 056 mayInstantiate=true, 057 mayExtend=false, 058 mayInvoke=true) 059public final class DirectoryEnvironmentConfig 060{ 061 /** The set of properties for the environment config. */ 062 private final Map<String, String> configProperties; 063 064 private final boolean checkIfServerIsRunning; 065 066 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 067 068 /** 069 * Creates a new directory environment configuration initialized 070 * from the system properties defined in the JVM. 071 */ 072 public DirectoryEnvironmentConfig() 073 { 074 this(true); 075 } 076 077 /** 078 * Creates a new directory environment configuration initialized from the 079 * system properties defined in the JVM. 080 * 081 * @param checkIfServerIsRunning 082 * If {@code true}, prevent any change when server is running. 083 */ 084 public DirectoryEnvironmentConfig(boolean checkIfServerIsRunning) 085 { 086 this(System.getProperties(), checkIfServerIsRunning); 087 } 088 089 090 091 /** 092 * Creates a new directory environment configuration initialized 093 * with a copy of the provided set of properties. 094 * 095 * @param properties The properties to use when initializing this 096 * environment configuration, or {@code null} 097 * to use an empty set of properties. 098 * @param checkIfServerIsRunning 099 * If {@code true}, prevent any change when server is running. 100 */ 101 public DirectoryEnvironmentConfig(Properties properties, boolean checkIfServerIsRunning) 102 { 103 this.checkIfServerIsRunning = checkIfServerIsRunning; 104 configProperties = new HashMap<>(); 105 if (properties != null) 106 { 107 Enumeration<?> propertyNames = properties.propertyNames(); 108 while (propertyNames.hasMoreElements()) 109 { 110 Object o = propertyNames.nextElement(); 111 configProperties.put(String.valueOf(o), 112 String.valueOf(properties.get(o))); 113 } 114 } 115 } 116 117 118 119 /** 120 * Creates a new directory environment configuration initialized 121 * with a copy of the provided set of properties. 122 * 123 * @param properties The properties to use when initializing this 124 * environment configuration, or {@code null} 125 * to use an empty set of properties. 126 * @param checkIfServerIsRunning 127 * If {@code true}, prevent any change when server is running. 128 */ 129 public DirectoryEnvironmentConfig(Map<String,String> properties, boolean checkIfServerIsRunning) 130 { 131 this.checkIfServerIsRunning = checkIfServerIsRunning; 132 if (properties == null) 133 { 134 configProperties = new HashMap<>(); 135 } 136 else 137 { 138 configProperties = new HashMap<>(properties); 139 } 140 } 141 142 143 144 /** 145 * Retrieves the property with the specified name. The check will 146 * first be made in the local config properties, but if no value is 147 * found then the JVM system properties will be checked. 148 * 149 * @param name The name of the property to retrieve. 150 * 151 * @return The property with the specified name, or {@code null} if 152 * no such property is defined. 153 */ 154 public String getProperty(String name) 155 { 156 String value = configProperties.get(name); 157 if (value == null) 158 { 159 value = System.getProperty(name); 160 } 161 162 return value; 163 } 164 165 166 167 /** 168 * Specifies a property with the given name and value. If a 169 * property is already defined with the given name, then its value 170 * will be replaced with the provided value, or the property will be 171 * removed if the given value is {@code null}. 172 * 173 * @param name The name of the property to set. 174 * @param value The value of the property to set, or {@code null} 175 * if the property is to be removed. 176 * 177 * @return The previous value held for the property, or 178 * {@code null} if it was not previously set. 179 * 180 * @throws InitializationException If the Directory Server is 181 * already running. 182 */ 183 public String setProperty(String name, String value) 184 throws InitializationException 185 { 186 checkServerIsRunning(); 187 188 if (value == null) 189 { 190 return configProperties.remove(name); 191 } 192 else 193 { 194 return configProperties.put(name, value); 195 } 196 } 197 198 /** 199 * Retrieves the directory that should be considered the server root. 200 * <p> 201 * The determination will first be based on the properties defined in this 202 * object. If no value is found there, then the JVM system properties will be 203 * checked, followed by an environment variable. If there is still no value, 204 * then the location of the config file, if available, is used to determine 205 * the root. 206 * 207 * @return The directory that should be considered the server root, or 208 * {@code null} if it can't be determined. 209 */ 210 public File getServerRoot() 211 { 212 File rootFile = null; 213 try 214 { 215 String serverRootPath = getProperty(PROPERTY_SERVER_ROOT); 216 if (serverRootPath == null) 217 { 218 serverRootPath = System.getenv(ENV_VAR_INSTALL_ROOT); 219 } 220 if (serverRootPath != null) 221 { 222 rootFile = new File(serverRootPath); 223 rootFile = forceNonRelativeFile(rootFile); 224 } 225 else 226 { 227 // Try to figure out root from the location of the configuration file 228 // Check for property first to avoid infinite loop with getConfigFile() 229 final String configFilePath = getProperty(PROPERTY_CONFIG_FILE); 230 if (configFilePath != null) 231 { 232 final File configDirFile = getConfigFile().getParentFile(); 233 if (configDirFile != null 234 && CONFIG_DIR_NAME.equals(configDirFile.getName())) 235 { 236 File parent = configDirFile.getParentFile(); 237 rootFile = forceNonRelativeFile(parent); 238 } 239 } 240 } 241 } 242 catch (Exception e) 243 { 244 logger.error(ERR_CONFIG_CANNOT_DETERMINE_SERVER_ROOT, 245 ENV_VAR_INSTALL_ROOT, e); 246 } 247 if (rootFile == null) 248 { 249 logger.error(ERR_CONFIG_CANNOT_DETERMINE_SERVER_ROOT, 250 ENV_VAR_INSTALL_ROOT); 251 } 252 return rootFile; 253 } 254 255 /** 256 * Retrieves the path of the directory that should be considered the server 257 * root. 258 * <p> 259 * This method uses the same rules than {@code getServerRoot} method, but 260 * never returns {@code null}. If no directory can be found it returns as a 261 * last resort the value of "user.dir" system property. 262 * 263 * @return the path of the directory that should be considered the server 264 * root. 265 */ 266 public String getServerRootAsString() { 267 File serverRoot = getServerRoot(); 268 if (serverRoot != null) 269 { 270 return serverRoot.getAbsolutePath(); 271 } 272 // We don't know where the server root is, so we'll have to assume it's 273 // the current working directory. 274 return System.getProperty("user.dir"); 275 } 276 277 /** 278 * Retrieves the directory that should be considered the instance 279 * root. 280 * 281 * @return The directory that should be considered the instance 282 * root or {@code null} if it can't be determined. 283 */ 284 public File getInstanceRoot() { 285 File serverRoot = getServerRoot(); 286 if (serverRoot != null) 287 { 288 File instanceRoot = new File(Utils.getInstancePathFromInstallPath(getServerRoot().getAbsolutePath())); 289 return forceNonRelativeFile(instanceRoot); 290 } 291 return null; 292 } 293 294 /** 295 * Retrieves the path of the directory that should be considered the instance 296 * root. 297 * <p> 298 * This method uses the same rules than {@code getInstanceRoot} method, but 299 * never returns {@code null}. If no directory can be found it returns as a 300 * last resort the value of "user.dir" system property. 301 * 302 * @return the path of the directory that should be considered the instance 303 * root. 304 */ 305 public String getInstanceRootAsString() 306 { 307 File instanceRoot = getInstanceRoot(); 308 if (instanceRoot != null) 309 { 310 return instanceRoot.getAbsolutePath(); 311 } 312 313 // We don't know where the instance root is, so we'll have to assume it's 314 // the current working directory. 315 return System.getProperty("user.dir"); 316 } 317 318 private File forceNonRelativeFile(File file) { 319 // Do a best effort to avoid having a relative representation 320 // (for instance to avoid having ../../../). 321 try 322 { 323 return file.getCanonicalFile(); 324 } 325 catch (IOException ioe) 326 { 327 return file.getAbsoluteFile(); 328 } 329 } 330 331 /** 332 * Retrieves the directory that should be considered the instance 333 * root. The determination will first be based on the properties 334 * defined in this config object. If no value is found there, then 335 * the JVM system properties will be checked, followed by an 336 * environment variable. 337 * 338 * @param serverRoot the server Root 339 * 340 * @return The directory that should be considered the instance 341 * root, or {@code null} if it is not defined. 342 */ 343 public static File getInstanceRootFromServerRoot(File serverRoot) 344 { 345 return new File(Utils.getInstancePathFromInstallPath(serverRoot.getAbsolutePath())); 346 } 347 348 349 350 /** 351 * Specifies the directory that should be considered the server 352 * root. Any relative path used in the server should be considered 353 * relative to the server root. 354 * 355 * @param serverRoot The directory that should be considered the 356 * server root. 357 * 358 * @return The previous server root, or {@code null} if there was 359 * none. 360 * 361 * @throws InitializationException If the Directory Server is 362 * already running or there is a 363 * problem with the provided 364 * server root. 365 */ 366 public File setServerRoot(File serverRoot) 367 throws InitializationException 368 { 369 checkServerIsRunning(); 370 371 if (!serverRoot.exists() || !serverRoot.isDirectory()) 372 { 373 throw new InitializationException( 374 ERR_DIRCFG_INVALID_SERVER_ROOT.get( 375 serverRoot.getAbsolutePath())); 376 } 377 378 return setPathProperty(PROPERTY_SERVER_ROOT, serverRoot); 379 } 380 381 /** 382 * Sets a path property. 383 * 384 * @param propertyName 385 * The property name to set. 386 * @param newPath 387 * The path to set on the property. 388 * @return The previous property value, or {@code null} if there was none. 389 * @throws InitializationException 390 * If the Directory Server is already running or there is a problem 391 * with the provided server root. 392 */ 393 private File setPathProperty(String propertyName, File newPath) 394 throws InitializationException 395 { 396 String normalizedNewPath; 397 try 398 { 399 normalizedNewPath = newPath.getCanonicalPath(); 400 } 401 catch (Exception e) 402 { 403 normalizedNewPath = newPath.getAbsolutePath(); 404 } 405 406 String oldPath = setProperty(propertyName, normalizedNewPath); 407 if (oldPath != null) 408 { 409 return new File(oldPath); 410 } 411 return null; 412 } 413 414 /** 415 * Specifies the directory that should be considered the instance 416 * root. Any relative path used in the server should be considered 417 * relative to the instance root. 418 * 419 * @param instanceRoot The directory that should be considered the 420 * instanceRoot root. 421 * 422 * @return The previous server root, or {@code null} if there was 423 * none. 424 * 425 * @throws InitializationException If the Directory Server is 426 * already running or there is a 427 * problem with the provided 428 * server root. 429 */ 430 public File setInstanceRoot(File instanceRoot) 431 throws InitializationException 432 { 433 checkServerIsRunning(); 434 435 if (!instanceRoot.exists() || !instanceRoot.isDirectory()) 436 { 437 throw new InitializationException( 438 ERR_DIRCFG_INVALID_SERVER_ROOT.get( 439 instanceRoot.getAbsolutePath())); 440 } 441 442 return setPathProperty(PROPERTY_INSTANCE_ROOT, instanceRoot); 443 } 444 445 446 /** 447 * Retrieves the configuration file that should be used to 448 * initialize the Directory Server config handler. If no default 449 * configuration file is specified, then the server will attempt to 450 * use "config/config.ldif" below the server root if it exists. 451 * 452 * @return The configuration file that should be used to initialize 453 * the Directory Server config handler, or {@code null} if 454 * no configuration file is defined. 455 */ 456 public File getConfigFile() 457 { 458 String configFilePath = getProperty(PROPERTY_CONFIG_FILE); 459 if (configFilePath == null) 460 { 461 File serverRoot = getServerRoot(); 462 if (serverRoot != null) 463 { 464 File instanceRoot = getInstanceRootFromServerRoot(serverRoot); 465 File configDir = new File(instanceRoot, CONFIG_DIR_NAME); 466 File configFile = new File(configDir, CONFIG_FILE_NAME); 467 if (configFile.exists()) 468 { 469 return configFile; 470 } 471 } 472 473 return null; 474 } 475 else 476 { 477 return new File(configFilePath); 478 } 479 } 480 481 482 483 /** 484 * Specifies the configuration file that should be used to 485 * initialize the Directory Server config handler. 486 * 487 * @param configFile The configuration file that should be used to 488 * initialize the Directory Server config 489 * handler. 490 * 491 * @return The previously-defined configuration file, or 492 * {@code null} if none was defined. 493 * 494 * @throws InitializationException If the Directory Server is 495 * already running or there is a 496 * problem with the provided 497 * configuration file. 498 */ 499 public File setConfigFile(File configFile) 500 throws InitializationException 501 { 502 checkServerIsRunning(); 503 504 if (!configFile.exists() || !configFile.isFile()) 505 { 506 throw new InitializationException( 507 ERR_DIRCFG_INVALID_CONFIG_FILE.get( 508 configFile.getAbsolutePath())); 509 } 510 511 return setPathProperty(PROPERTY_CONFIG_FILE, configFile); 512 } 513 514 515 516 /** 517 * Retrieves the class that provides the Directory Server 518 * configuration handler implementation. If no config handler class 519 * is defined, or if a problem occurs while attempting to determine 520 * the config handler class, then a default class of 521 * org.opends.server.extensions.ConfigFileHandler will be returned. 522 * 523 * @return The class that provides the Directory Server 524 * configuration handler implementation. 525 */ 526 public Class getConfigClass() 527 { 528 String className = getProperty(PROPERTY_CONFIG_CLASS); 529 if (className == null) 530 { 531 return ConfigFileHandler.class; 532 } 533 else 534 { 535 try 536 { 537 return Class.forName(className); 538 } 539 catch (Exception e) 540 { 541 return ConfigFileHandler.class; 542 } 543 } 544 } 545 546 547 548 /** 549 * Specifies the class that provides the Directory Server 550 * configuration handler implementation. The class must be a 551 * subclass of the org.opends.server.api.ConfigHandler superclass. 552 * 553 * @param configClass The class that proviedes the Directory 554 * Server configuration handler implementation. 555 * 556 * @return The class that was previously configured to provide the 557 * Directory Server configuration handler implementation, 558 * or {@code null} if none was defined. 559 * 560 * @throws InitializationException If the Directory Server is 561 * already running or there is a 562 * problem with the provided 563 * config handler class. 564 */ 565 public Class setConfigClass(Class configClass) 566 throws InitializationException 567 { 568 checkServerIsRunning(); 569 570 if (!ConfigHandler.class.isAssignableFrom(configClass)) 571 { 572 throw new InitializationException( 573 ERR_DIRCFG_INVALID_CONFIG_CLASS.get( 574 configClass.getName())); 575 } 576 577 String oldClassName = setProperty(PROPERTY_CONFIG_CLASS, 578 configClass.getName()); 579 if (oldClassName == null) 580 { 581 return null; 582 } 583 else 584 { 585 try 586 { 587 return Class.forName(oldClassName); 588 } 589 catch (Exception e) 590 { 591 return null; 592 } 593 } 594 } 595 596 597 598 /** 599 * Indicates whether the Directory Server should attempt to start 600 * with the "last known good" configuration rather than the current 601 * active configuration file. Note that if there is no "last known 602 * good" configuration file available, then the server should try to 603 * start using the current, active configuration file. If no 604 * explicit value is defined, then a default result of {@code false} 605 * will be returned. 606 * 607 * @return {@code true} if the Directory Server should attempt to 608 * start using the "last known good" configuration, or 609 * {@code false} if it should try to start using the 610 * active configuration. 611 */ 612 public boolean useLastKnownGoodConfiguration() 613 { 614 return isPropertyTrue(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG); 615 } 616 617 /** 618 * Indicates whether the property value is set and equal to "true" for the 619 * supplied property name. 620 * 621 * @param propertyName 622 * the name of the property to be checked 623 * @return {@code true} if the property is set and the property value is 624 * <code>"true"</code>, {@code false} otherwise . 625 */ 626 private boolean isPropertyTrue(String propertyName) 627 { 628 return "true".equalsIgnoreCase(getProperty(propertyName)); 629 } 630 631 /** 632 * Specifies whether the Directory Server should attempt to start 633 * using the last known good configuration rather than the 634 * current active configuration. 635 * 636 * @param useLastKnownGoodConfiguration Indicates whether the 637 * Directory Server should 638 * attempt to start using the 639 * last known good 640 * configuration. 641 * 642 * @return The previous setting for this configuration option. If 643 * no previous value was specified, then {@code false} will 644 * be returned. 645 * 646 * @throws InitializationException If the Directory Server is 647 * already running. 648 */ 649 public boolean setUseLastKnownGoodConfiguration( 650 boolean useLastKnownGoodConfiguration) 651 throws InitializationException 652 { 653 return setBooleanProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG, 654 useLastKnownGoodConfiguration); 655 } 656 657 658 659 /** 660 * Indicates whether the Directory Server should maintain an archive 661 * of previous configurations. If no explicit value is defined, 662 * then a default result of {@code true} will be returned. 663 * 664 * @return {@code true} if the Directory Server should maintain an 665 * archive of previous configurations, or {@code false} if 666 * not. 667 */ 668 public boolean maintainConfigArchive() 669 { 670 String maintainArchiveStr = 671 getProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE); 672 return maintainArchiveStr == null 673 || !"false".equalsIgnoreCase(maintainArchiveStr); 674 } 675 676 677 678 /** 679 * Specifies whether the Directory Server should maintain an archive 680 * of previous configurations. 681 * 682 * @param maintainConfigArchive Indicates whether the Directory 683 * Server should maintain an archive 684 * of previous configurations. 685 * 686 * @return The previous setting for this configuration option. If 687 * no previous value was specified, then {@code true} will 688 * be returned. 689 * 690 * @throws InitializationException If the Directory Server is 691 * already running. 692 */ 693 public boolean setMaintainConfigArchive( 694 boolean maintainConfigArchive) 695 throws InitializationException 696 { 697 checkServerIsRunning(); 698 699 String oldMaintainStr = 700 setProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE, 701 String.valueOf(maintainConfigArchive)); 702 return oldMaintainStr == null || !"false".equalsIgnoreCase(oldMaintainStr); 703 } 704 705 706 707 /** 708 * Retrieves the maximum number of archived configurations that the 709 * Directory Server should maintain. If no value is defined, then a 710 * value of zero will be returned. 711 * 712 * @return The maximum number of archived configurations that the 713 * Directory Server should maintain, or zero if there 714 * should not be any limit. 715 */ 716 public int getMaxConfigArchiveSize() 717 { 718 String maxSizeStr = 719 getProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE); 720 if (maxSizeStr == null) 721 { 722 return 0; 723 } 724 725 try 726 { 727 int maxSize = Integer.parseInt(maxSizeStr); 728 if (maxSize > 0) 729 { 730 return maxSize; 731 } 732 else 733 { 734 return 0; 735 } 736 } 737 catch (Exception e) 738 { 739 return 0; 740 } 741 } 742 743 744 745 /** 746 * Specifies the maximum number of archived configurations that the 747 * Directory Server should maintain. A value that is less than or 748 * equal to zero may be used to indicate that there should not be 749 * any limit to the number of archived configurations. 750 * 751 * @param maxConfigArchiveSize The maximum number of archived 752 * configurations that the Directory 753 * Server should maintain. 754 * 755 * @return The previous setting for this configuration option. If 756 * no previous value was specified, then zero will be 757 * returned. 758 * 759 * @throws InitializationException If the Directory Server is 760 * already running. 761 */ 762 public int setMaxConfigArchiveSize(int maxConfigArchiveSize) 763 throws InitializationException 764 { 765 checkServerIsRunning(); 766 767 if (maxConfigArchiveSize < 0) 768 { 769 maxConfigArchiveSize = 0; 770 } 771 772 String oldMaxSizeStr = 773 setProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE, 774 String.valueOf(maxConfigArchiveSize)); 775 if (oldMaxSizeStr == null) 776 { 777 return 0; 778 } 779 else 780 { 781 try 782 { 783 int oldMaxSize = Integer.parseInt(oldMaxSizeStr); 784 if (oldMaxSize > 0) 785 { 786 return oldMaxSize; 787 } 788 else 789 { 790 return 0; 791 } 792 } 793 catch (Exception e) 794 { 795 return 0; 796 } 797 } 798 } 799 800 801 802 /** 803 * Retrieves the directory that contains the server schema 804 * configuration files. If no value is defined, but a default 805 * directory of "config/schema" exists below the server root, then 806 * that will be returned. 807 * 808 * @return The directory that contains the server schema 809 * configuration files, or {@code null} if none is defined. 810 */ 811 public File getSchemaDirectory() 812 { 813 String schemaDirectoryPath = 814 getProperty(PROPERTY_SCHEMA_DIRECTORY); 815 if (schemaDirectoryPath == null) 816 { 817 File serverRoot = getServerRoot(); 818 if (serverRoot != null) 819 { 820 File instanceRoot = 821 getInstanceRootFromServerRoot(serverRoot); 822 File schemaDir = new File(instanceRoot.getAbsolutePath() 823 + File.separator + PATH_SCHEMA_DIR); 824 if (schemaDir.exists() && schemaDir.isDirectory()) 825 { 826 return schemaDir; 827 } 828 } 829 return null; 830 } 831 else 832 { 833 return new File(schemaDirectoryPath); 834 } 835 } 836 837 838 839 /** 840 * Specifies the directory that should contain the server schema 841 * configuration files. It must exist and must be a directory. 842 * 843 * @param schemaDirectory The directory that should contain the 844 * server schema configuration files. 845 * 846 * @return The previously-defined schema configuration directory, 847 * or {@code null} if none was defined. 848 * 849 * @throws InitializationException If the Directory Server is 850 * already running or there is a 851 * problem with the provided 852 * schema directory. 853 */ 854 public File setSchemaDirectory(File schemaDirectory) 855 throws InitializationException 856 { 857 checkServerIsRunning(); 858 859 if (!schemaDirectory.exists() || !schemaDirectory.isDirectory()) 860 { 861 throw new InitializationException( 862 ERR_DIRCFG_INVALID_SCHEMA_DIRECTORY.get( 863 schemaDirectory.getAbsolutePath())); 864 } 865 866 return setPathProperty(PROPERTY_SCHEMA_DIRECTORY, schemaDirectory); 867 } 868 869 870 871 /** 872 * Retrieves the directory that should be used to hold the server 873 * lock files. If no value is defined, then the server will attempt 874 * to use a default directory of "locks" below the server root. 875 * 876 * @return The directory that should be used to hold the server 877 * lock files, or {@code null} if it cannot be determined. 878 */ 879 public File getLockDirectory() 880 { 881 String lockFilePath = getProperty(PROPERTY_LOCK_DIRECTORY); 882 if (lockFilePath == null) 883 { 884 File serverRoot = getServerRoot(); 885 if (serverRoot == null) 886 { 887 return null; 888 } 889 else 890 { 891 File instanceRoot = getInstanceRootFromServerRoot(serverRoot); 892 return new File(instanceRoot, LOCKS_DIRECTORY); 893 } 894 } 895 else 896 { 897 return new File(lockFilePath); 898 } 899 } 900 901 902 903 /** 904 * Specifies the directory that should be used to hold the server 905 * lock files. If the specified path already exists, then it must 906 * be a directory and its contents must be writable by the server. 907 * If it does not exist, then its parent directory must exist and 908 * the server should have permission to create a new subdirectory in 909 * it. 910 * 911 * @param lockDirectory The directory that should be used to hold 912 * the server lock files. 913 * 914 * @return The previously-defined lock directory, or {@code null} 915 * if none was defined. 916 * 917 * @throws InitializationException If the Directory Server is 918 * already running or there is a 919 * problem with the provided lock 920 * directory. 921 */ 922 public File setLockDirectory(File lockDirectory) 923 throws InitializationException 924 { 925 checkServerIsRunning(); 926 927 if (lockDirectory.exists()) 928 { 929 if (! lockDirectory.isDirectory()) 930 { 931 throw new InitializationException( 932 ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get( 933 lockDirectory.getAbsolutePath())); 934 } 935 } 936 else 937 { 938 File parentFile = lockDirectory.getParentFile(); 939 if (!parentFile.exists() || !parentFile.isDirectory()) 940 { 941 throw new InitializationException( 942 ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get( 943 lockDirectory.getAbsolutePath())); 944 } 945 } 946 947 return setPathProperty(PROPERTY_LOCK_DIRECTORY, lockDirectory); 948 } 949 950 951 952 /** 953 * Indicates whether the Directory Server startup process should 954 * skip the connection handler creation and initialization phases. 955 * 956 * @return {@code true} if the Directory Server should not start 957 * its connection handlers, or {@code false} if the 958 * connection handlers should be enabled. 959 */ 960 public boolean disableConnectionHandlers() 961 { 962 return isPropertyTrue(PROPERTY_DISABLE_CONNECTION_HANDLERS); 963 } 964 965 /** 966 * Indicates whether the Directory Server startup process should 967 * skip the synchronization provider creation and initialization 968 * phases. 969 * 970 * @return {@code true} if the Directory Server should not start 971 * its synchronization provider, or {@code false} if the 972 * synchronization provider should be enabled. 973 */ 974 public boolean disableSynchronization() 975 { 976 return isPropertyTrue(PROPERTY_DISABLE_SYNCHRONIZATION); 977 } 978 979 /** 980 * Indicates whether the Directory Server startup process should 981 * skip the synchronization between admin data and the 982 * configuration. 983 * 984 * @return {@code true} if the Directory Server should start 985 * synchronization between admin data and the 986 * configuration. 987 */ 988 public boolean disableAdminDataSynchronization() 989 { 990 return isPropertyTrue(PROPERTY_DISABLE_ADMIN_DATA_SYNCHRONIZATION); 991 } 992 993 /** 994 * Specifies whether the Directory Server startup process should 995 * skip the connection handler creation and initialization phases. 996 * 997 * @param disableConnectionHandlers Indicates whether the 998 * Directory Server should skip 999 * the connection handler 1000 * creation and initialization 1001 * phases. 1002 * 1003 * @return The previous setting for this configuration option. If 1004 * no previous value was specified, then {@code false} will 1005 * be returned. 1006 * 1007 * @throws InitializationException If the Directory Server is 1008 * already running. 1009 */ 1010 public boolean setDisableConnectionHandlers( 1011 boolean disableConnectionHandlers) 1012 throws InitializationException 1013 { 1014 return setBooleanProperty(PROPERTY_DISABLE_CONNECTION_HANDLERS, 1015 disableConnectionHandlers); 1016 } 1017 1018 /** 1019 * Sets a boolean property. 1020 * 1021 * @param propertyName 1022 * the property name to set 1023 * @param newValue 1024 * the new value to set for the property 1025 * @return The previous setting for this configuration option. If no previous 1026 * value was specified, then {@code false} will be returned. 1027 * @throws InitializationException 1028 * If the Directory Server is already running or there is a problem 1029 * with the provided server root. 1030 */ 1031 private boolean setBooleanProperty(String propertyName, boolean newValue) 1032 throws InitializationException 1033 { 1034 checkServerIsRunning(); 1035 1036 final String oldValue = setProperty(propertyName, String.valueOf(newValue)); 1037 return "true".equalsIgnoreCase(oldValue); 1038 } 1039 1040 /** 1041 * Indicates whether all threads created by the Directory Server 1042 * should be created as daemon threads. 1043 * 1044 * @return {@code true} if all threads created by the Directory 1045 * Server should be created as daemon threads, or 1046 * {@code false} if not. 1047 */ 1048 public boolean forceDaemonThreads() 1049 { 1050 return isPropertyTrue(PROPERTY_FORCE_DAEMON_THREADS); 1051 } 1052 1053 1054 1055 /** 1056 * Specifies whether all threads created by the Directory Server 1057 * should be created as daemon threads. 1058 * 1059 * @param forceDaemonThreads Indicates whether all threads created 1060 * by the Directory Server should be 1061 * created as daemon threads. 1062 * 1063 * @return The previous setting for this configuration option. If 1064 * no previous value was specified, then {@code false} will 1065 * be returned. 1066 * 1067 * @throws InitializationException If the Directory Server is 1068 * already running. 1069 */ 1070 public boolean setForceDaemonThreads(boolean forceDaemonThreads) 1071 throws InitializationException 1072 { 1073 return setBooleanProperty(PROPERTY_FORCE_DAEMON_THREADS, 1074 forceDaemonThreads); 1075 } 1076 1077 1078 1079 /** 1080 * Indicates whether the Directory Server should be allowed to use 1081 * the {@code Runtime.exec()} method to be able to launch external 1082 * commands on the underlying system. 1083 * 1084 * @return {@code true} if the Directory Server should be allowed 1085 * to use {@code Runtime.exec()}, or {@code false} if not. 1086 */ 1087 public boolean disableExec() 1088 { 1089 return isPropertyTrue(PROPERTY_DISABLE_EXEC); 1090 } 1091 1092 1093 1094 /** 1095 * Specifies whether the Directory Server should be allowed to use 1096 * the {@code Runtime.exec()} method to be able to launch external 1097 * commands on the underlying system. 1098 * 1099 * @param disableExec Indicates whether the Directory Server 1100 * should be allowed to launch external 1101 * commands on the underlying system. 1102 * 1103 * @return The previous setting for this configuration option. If 1104 * no previous value was specified, then {@code false} will 1105 * be returned. 1106 * 1107 * @throws InitializationException If the Directory Server is 1108 * already running. 1109 */ 1110 public boolean setDisableExec(boolean disableExec) 1111 throws InitializationException 1112 { 1113 return setBooleanProperty(PROPERTY_DISABLE_EXEC, disableExec); 1114 } 1115 1116 1117 1118 /** Throws an exception if server is running and it is not allowed. */ 1119 private void checkServerIsRunning() throws InitializationException 1120 { 1121 if (checkIfServerIsRunning && DirectoryServer.isRunning()) 1122 { 1123 throw new InitializationException( 1124 ERR_DIRCFG_SERVER_ALREADY_RUNNING.get()); 1125 } 1126 } 1127}