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 String path = null; 322 try 323 { 324 path = file.getCanonicalPath(); 325 } 326 catch (IOException ioe) 327 { 328 path = file.getAbsolutePath(); 329 } 330 return new File(path); 331 } 332 333 /** 334 * Retrieves the directory that should be considered the instance 335 * root. The determination will first be based on the properties 336 * defined in this config object. If no value is found there, then 337 * the JVM system properties will be checked, followed by an 338 * environment variable. 339 * 340 * @param serverRoot the server Root 341 * 342 * @return The directory that should be considered the instance 343 * root, or {@code null} if it is not defined. 344 */ 345 public static File getInstanceRootFromServerRoot(File serverRoot) 346 { 347 return new File(Utils.getInstancePathFromInstallPath(serverRoot.getAbsolutePath())); 348 } 349 350 351 352 /** 353 * Specifies the directory that should be considered the server 354 * root. Any relative path used in the server should be considered 355 * relative to the server root. 356 * 357 * @param serverRoot The directory that should be considered the 358 * server root. 359 * 360 * @return The previous server root, or {@code null} if there was 361 * none. 362 * 363 * @throws InitializationException If the Directory Server is 364 * already running or there is a 365 * problem with the provided 366 * server root. 367 */ 368 public File setServerRoot(File serverRoot) 369 throws InitializationException 370 { 371 checkServerIsRunning(); 372 373 if (!serverRoot.exists() || !serverRoot.isDirectory()) 374 { 375 throw new InitializationException( 376 ERR_DIRCFG_INVALID_SERVER_ROOT.get( 377 serverRoot.getAbsolutePath())); 378 } 379 380 return setPathProperty(PROPERTY_SERVER_ROOT, serverRoot); 381 } 382 383 /** 384 * Sets a path property. 385 * 386 * @param propertyName 387 * The property name to set. 388 * @param newPath 389 * The path to set on the property. 390 * @return The previous property value, or {@code null} if there was none. 391 * @throws InitializationException 392 * If the Directory Server is already running or there is a problem 393 * with the provided server root. 394 */ 395 private File setPathProperty(String propertyName, File newPath) 396 throws InitializationException 397 { 398 String normalizedNewPath; 399 try 400 { 401 normalizedNewPath = newPath.getCanonicalPath(); 402 } 403 catch (Exception e) 404 { 405 normalizedNewPath = newPath.getAbsolutePath(); 406 } 407 408 String oldPath = setProperty(propertyName, normalizedNewPath); 409 if (oldPath != null) 410 { 411 return new File(oldPath); 412 } 413 return null; 414 } 415 416 /** 417 * Specifies the directory that should be considered the instance 418 * root. Any relative path used in the server should be considered 419 * relative to the instance root. 420 * 421 * @param instanceRoot The directory that should be considered the 422 * instanceRoot root. 423 * 424 * @return The previous server root, or {@code null} if there was 425 * none. 426 * 427 * @throws InitializationException If the Directory Server is 428 * already running or there is a 429 * problem with the provided 430 * server root. 431 */ 432 public File setInstanceRoot(File instanceRoot) 433 throws InitializationException 434 { 435 checkServerIsRunning(); 436 437 if (!instanceRoot.exists() || !instanceRoot.isDirectory()) 438 { 439 throw new InitializationException( 440 ERR_DIRCFG_INVALID_SERVER_ROOT.get( 441 instanceRoot.getAbsolutePath())); 442 } 443 444 return setPathProperty(PROPERTY_INSTANCE_ROOT, instanceRoot); 445 } 446 447 448 /** 449 * Retrieves the configuration file that should be used to 450 * initialize the Directory Server config handler. If no default 451 * configuration file is specified, then the server will attempt to 452 * use "config/config.ldif" below the server root if it exists. 453 * 454 * @return The configuration file that should be used to initialize 455 * the Directory Server config handler, or {@code null} if 456 * no configuration file is defined. 457 */ 458 public File getConfigFile() 459 { 460 String configFilePath = getProperty(PROPERTY_CONFIG_FILE); 461 if (configFilePath == null) 462 { 463 File serverRoot = getServerRoot(); 464 if (serverRoot != null) 465 { 466 File instanceRoot = getInstanceRootFromServerRoot(serverRoot); 467 File configDir = new File(instanceRoot, CONFIG_DIR_NAME); 468 File configFile = new File(configDir, CONFIG_FILE_NAME); 469 if (configFile.exists()) 470 { 471 return configFile; 472 } 473 } 474 475 return null; 476 } 477 else 478 { 479 return new File(configFilePath); 480 } 481 } 482 483 484 485 /** 486 * Specifies the configuration file that should be used to 487 * initialize the Directory Server config handler. 488 * 489 * @param configFile The configuration file that should be used to 490 * initialize the Directory Server config 491 * handler. 492 * 493 * @return The previously-defined configuration file, or 494 * {@code null} if none was defined. 495 * 496 * @throws InitializationException If the Directory Server is 497 * already running or there is a 498 * problem with the provided 499 * configuration file. 500 */ 501 public File setConfigFile(File configFile) 502 throws InitializationException 503 { 504 checkServerIsRunning(); 505 506 if (!configFile.exists() || !configFile.isFile()) 507 { 508 throw new InitializationException( 509 ERR_DIRCFG_INVALID_CONFIG_FILE.get( 510 configFile.getAbsolutePath())); 511 } 512 513 return setPathProperty(PROPERTY_CONFIG_FILE, configFile); 514 } 515 516 517 518 /** 519 * Retrieves the class that provides the Directory Server 520 * configuration handler implementation. If no config handler class 521 * is defined, or if a problem occurs while attempting to determine 522 * the config handler class, then a default class of 523 * org.opends.server.extensions.ConfigFileHandler will be returned. 524 * 525 * @return The class that provides the Directory Server 526 * configuration handler implementation. 527 */ 528 public Class getConfigClass() 529 { 530 String className = getProperty(PROPERTY_CONFIG_CLASS); 531 if (className == null) 532 { 533 return ConfigFileHandler.class; 534 } 535 else 536 { 537 try 538 { 539 return Class.forName(className); 540 } 541 catch (Exception e) 542 { 543 return ConfigFileHandler.class; 544 } 545 } 546 } 547 548 549 550 /** 551 * Specifies the class that provides the Directory Server 552 * configuration handler implementation. The class must be a 553 * subclass of the org.opends.server.api.ConfigHandler superclass. 554 * 555 * @param configClass The class that proviedes the Directory 556 * Server configuration handler implementation. 557 * 558 * @return The class that was previously configured to provide the 559 * Directory Server configuration handler implementation, 560 * or {@code null} if none was defined. 561 * 562 * @throws InitializationException If the Directory Server is 563 * already running or there is a 564 * problem with the provided 565 * config handler class. 566 */ 567 public Class setConfigClass(Class configClass) 568 throws InitializationException 569 { 570 checkServerIsRunning(); 571 572 if (!ConfigHandler.class.isAssignableFrom(configClass)) 573 { 574 throw new InitializationException( 575 ERR_DIRCFG_INVALID_CONFIG_CLASS.get( 576 configClass.getName())); 577 } 578 579 String oldClassName = setProperty(PROPERTY_CONFIG_CLASS, 580 configClass.getName()); 581 if (oldClassName == null) 582 { 583 return null; 584 } 585 else 586 { 587 try 588 { 589 return Class.forName(oldClassName); 590 } 591 catch (Exception e) 592 { 593 return null; 594 } 595 } 596 } 597 598 599 600 /** 601 * Indicates whether the Directory Server should attempt to start 602 * with the "last known good" configuration rather than the current 603 * active configuration file. Note that if there is no "last known 604 * good" configuration file available, then the server should try to 605 * start using the current, active configuration file. If no 606 * explicit value is defined, then a default result of {@code false} 607 * will be returned. 608 * 609 * @return {@code true} if the Directory Server should attempt to 610 * start using the "last known good" configuration, or 611 * {@code false} if it should try to start using the 612 * active configuration. 613 */ 614 public boolean useLastKnownGoodConfiguration() 615 { 616 return isPropertyTrue(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG); 617 } 618 619 /** 620 * Indicates whether the property value is set and equal to "true" for the 621 * supplied property name. 622 * 623 * @param propertyName 624 * the name of the property to be checked 625 * @return {@code true} if the property is set and the property value is 626 * <code>"true"</code>, {@code false} otherwise . 627 */ 628 private boolean isPropertyTrue(String propertyName) 629 { 630 return "true".equalsIgnoreCase(getProperty(propertyName)); 631 } 632 633 /** 634 * Specifies whether the Directory Server should attempt to start 635 * using the last known good configuration rather than the 636 * current active configuration. 637 * 638 * @param useLastKnownGoodConfiguration Indicates whether the 639 * Directory Server should 640 * attempt to start using the 641 * last known good 642 * configuration. 643 * 644 * @return The previous setting for this configuration option. If 645 * no previous value was specified, then {@code false} will 646 * be returned. 647 * 648 * @throws InitializationException If the Directory Server is 649 * already running. 650 */ 651 public boolean setUseLastKnownGoodConfiguration( 652 boolean useLastKnownGoodConfiguration) 653 throws InitializationException 654 { 655 return setBooleanProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG, 656 useLastKnownGoodConfiguration); 657 } 658 659 660 661 /** 662 * Indicates whether the Directory Server should maintain an archive 663 * of previous configurations. If no explicit value is defined, 664 * then a default result of {@code true} will be returned. 665 * 666 * @return {@code true} if the Directory Server should maintain an 667 * archive of previous configurations, or {@code false} if 668 * not. 669 */ 670 public boolean maintainConfigArchive() 671 { 672 String maintainArchiveStr = 673 getProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE); 674 return maintainArchiveStr == null 675 || !"false".equalsIgnoreCase(maintainArchiveStr); 676 } 677 678 679 680 /** 681 * Specifies whether the Directory Server should maintain an archive 682 * of previous configurations. 683 * 684 * @param maintainConfigArchive Indicates whether the Directory 685 * Server should maintain an archive 686 * of previous configurations. 687 * 688 * @return The previous setting for this configuration option. If 689 * no previous value was specified, then {@code true} will 690 * be returned. 691 * 692 * @throws InitializationException If the Directory Server is 693 * already running. 694 */ 695 public boolean setMaintainConfigArchive( 696 boolean maintainConfigArchive) 697 throws InitializationException 698 { 699 checkServerIsRunning(); 700 701 String oldMaintainStr = 702 setProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE, 703 String.valueOf(maintainConfigArchive)); 704 return oldMaintainStr == null || !"false".equalsIgnoreCase(oldMaintainStr); 705 } 706 707 708 709 /** 710 * Retrieves the maximum number of archived configurations that the 711 * Directory Server should maintain. If no value is defined, then a 712 * value of zero will be returned. 713 * 714 * @return The maximum number of archived configurations that the 715 * Directory Server should maintain, or zero if there 716 * should not be any limit. 717 */ 718 public int getMaxConfigArchiveSize() 719 { 720 String maxSizeStr = 721 getProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE); 722 if (maxSizeStr == null) 723 { 724 return 0; 725 } 726 727 try 728 { 729 int maxSize = Integer.parseInt(maxSizeStr); 730 if (maxSize > 0) 731 { 732 return maxSize; 733 } 734 else 735 { 736 return 0; 737 } 738 } 739 catch (Exception e) 740 { 741 return 0; 742 } 743 } 744 745 746 747 /** 748 * Specifies the maximum number of archived configurations that the 749 * Directory Server should maintain. A value that is less than or 750 * equal to zero may be used to indicate that there should not be 751 * any limit to the number of archived configurations. 752 * 753 * @param maxConfigArchiveSize The maximum number of archived 754 * configurations that the Directory 755 * Server should maintain. 756 * 757 * @return The previous setting for this configuration option. If 758 * no previous value was specified, then zero will be 759 * returned. 760 * 761 * @throws InitializationException If the Directory Server is 762 * already running. 763 */ 764 public int setMaxConfigArchiveSize(int maxConfigArchiveSize) 765 throws InitializationException 766 { 767 checkServerIsRunning(); 768 769 if (maxConfigArchiveSize < 0) 770 { 771 maxConfigArchiveSize = 0; 772 } 773 774 String oldMaxSizeStr = 775 setProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE, 776 String.valueOf(maxConfigArchiveSize)); 777 if (oldMaxSizeStr == null) 778 { 779 return 0; 780 } 781 else 782 { 783 try 784 { 785 int oldMaxSize = Integer.parseInt(oldMaxSizeStr); 786 if (oldMaxSize > 0) 787 { 788 return oldMaxSize; 789 } 790 else 791 { 792 return 0; 793 } 794 } 795 catch (Exception e) 796 { 797 return 0; 798 } 799 } 800 } 801 802 803 804 /** 805 * Retrieves the directory that contains the server schema 806 * configuration files. If no value is defined, but a default 807 * directory of "config/schema" exists below the server root, then 808 * that will be returned. 809 * 810 * @return The directory that contains the server schema 811 * configuration files, or {@code null} if none is defined. 812 */ 813 public File getSchemaDirectory() 814 { 815 String schemaDirectoryPath = 816 getProperty(PROPERTY_SCHEMA_DIRECTORY); 817 if (schemaDirectoryPath == null) 818 { 819 File serverRoot = getServerRoot(); 820 if (serverRoot != null) 821 { 822 File instanceRoot = 823 getInstanceRootFromServerRoot(serverRoot); 824 File schemaDir = new File(instanceRoot.getAbsolutePath() 825 + File.separator + PATH_SCHEMA_DIR); 826 if (schemaDir.exists() && schemaDir.isDirectory()) 827 { 828 return schemaDir; 829 } 830 } 831 return null; 832 } 833 else 834 { 835 return new File(schemaDirectoryPath); 836 } 837 } 838 839 840 841 /** 842 * Specifies the directory that should contain the server schema 843 * configuration files. It must exist and must be a directory. 844 * 845 * @param schemaDirectory The directory that should contain the 846 * server schema configuration files. 847 * 848 * @return The previously-defined schema configuration directory, 849 * or {@code null} if none was defined. 850 * 851 * @throws InitializationException If the Directory Server is 852 * already running or there is a 853 * problem with the provided 854 * schema directory. 855 */ 856 public File setSchemaDirectory(File schemaDirectory) 857 throws InitializationException 858 { 859 checkServerIsRunning(); 860 861 if (!schemaDirectory.exists() || !schemaDirectory.isDirectory()) 862 { 863 throw new InitializationException( 864 ERR_DIRCFG_INVALID_SCHEMA_DIRECTORY.get( 865 schemaDirectory.getAbsolutePath())); 866 } 867 868 return setPathProperty(PROPERTY_SCHEMA_DIRECTORY, schemaDirectory); 869 } 870 871 872 873 /** 874 * Retrieves the directory that should be used to hold the server 875 * lock files. If no value is defined, then the server will attempt 876 * to use a default directory of "locks" below the server root. 877 * 878 * @return The directory that should be used to hold the server 879 * lock files, or {@code null} if it cannot be determined. 880 */ 881 public File getLockDirectory() 882 { 883 String lockFilePath = getProperty(PROPERTY_LOCK_DIRECTORY); 884 if (lockFilePath == null) 885 { 886 File serverRoot = getServerRoot(); 887 if (serverRoot == null) 888 { 889 return null; 890 } 891 else 892 { 893 File instanceRoot = getInstanceRootFromServerRoot(serverRoot); 894 return new File(instanceRoot, LOCKS_DIRECTORY); 895 } 896 } 897 else 898 { 899 return new File(lockFilePath); 900 } 901 } 902 903 904 905 /** 906 * Specifies the directory that should be used to hold the server 907 * lock files. If the specified path already exists, then it must 908 * be a directory and its contents must be writable by the server. 909 * If it does not exist, then its parent directory must exist and 910 * the server should have permission to create a new subdirectory in 911 * it. 912 * 913 * @param lockDirectory The directory that should be used to hold 914 * the server lock files. 915 * 916 * @return The previously-defined lock directory, or {@code null} 917 * if none was defined. 918 * 919 * @throws InitializationException If the Directory Server is 920 * already running or there is a 921 * problem with the provided lock 922 * directory. 923 */ 924 public File setLockDirectory(File lockDirectory) 925 throws InitializationException 926 { 927 checkServerIsRunning(); 928 929 if (lockDirectory.exists()) 930 { 931 if (! lockDirectory.isDirectory()) 932 { 933 throw new InitializationException( 934 ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get( 935 lockDirectory.getAbsolutePath())); 936 } 937 } 938 else 939 { 940 File parentFile = lockDirectory.getParentFile(); 941 if (!parentFile.exists() || !parentFile.isDirectory()) 942 { 943 throw new InitializationException( 944 ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get( 945 lockDirectory.getAbsolutePath())); 946 } 947 } 948 949 return setPathProperty(PROPERTY_LOCK_DIRECTORY, lockDirectory); 950 } 951 952 953 954 /** 955 * Indicates whether the Directory Server startup process should 956 * skip the connection handler creation and initialization phases. 957 * 958 * @return {@code true} if the Directory Server should not start 959 * its connection handlers, or {@code false} if the 960 * connection handlers should be enabled. 961 */ 962 public boolean disableConnectionHandlers() 963 { 964 return isPropertyTrue(PROPERTY_DISABLE_CONNECTION_HANDLERS); 965 } 966 967 /** 968 * Indicates whether the Directory Server startup process should 969 * skip the synchronization provider creation and initialization 970 * phases. 971 * 972 * @return {@code true} if the Directory Server should not start 973 * its synchronization provider, or {@code false} if the 974 * synchronization provider should be enabled. 975 */ 976 public boolean disableSynchronization() 977 { 978 return isPropertyTrue(PROPERTY_DISABLE_SYNCHRONIZATION); 979 } 980 981 /** 982 * Indicates whether the Directory Server startup process should 983 * skip the synchronization between admin data and the 984 * configuration. 985 * 986 * @return {@code true} if the Directory Server should start 987 * synchronization between admin data and the 988 * configuration. 989 */ 990 public boolean disableAdminDataSynchronization() 991 { 992 return isPropertyTrue(PROPERTY_DISABLE_ADMIN_DATA_SYNCHRONIZATION); 993 } 994 995 /** 996 * Specifies whether the Directory Server startup process should 997 * skip the connection handler creation and initialization phases. 998 * 999 * @param disableConnectionHandlers Indicates whether the 1000 * Directory Server should skip 1001 * the connection handler 1002 * creation and initialization 1003 * phases. 1004 * 1005 * @return The previous setting for this configuration option. If 1006 * no previous value was specified, then {@code false} will 1007 * be returned. 1008 * 1009 * @throws InitializationException If the Directory Server is 1010 * already running. 1011 */ 1012 public boolean setDisableConnectionHandlers( 1013 boolean disableConnectionHandlers) 1014 throws InitializationException 1015 { 1016 return setBooleanProperty(PROPERTY_DISABLE_CONNECTION_HANDLERS, 1017 disableConnectionHandlers); 1018 } 1019 1020 /** 1021 * Sets a boolean property. 1022 * 1023 * @param propertyName 1024 * the property name to set 1025 * @param newValue 1026 * the new value to set for the property 1027 * @return The previous setting for this configuration option. If no previous 1028 * value was specified, then {@code false} will be returned. 1029 * @throws InitializationException 1030 * If the Directory Server is already running or there is a problem 1031 * with the provided server root. 1032 */ 1033 private boolean setBooleanProperty(String propertyName, boolean newValue) 1034 throws InitializationException 1035 { 1036 checkServerIsRunning(); 1037 1038 final String oldValue = setProperty(propertyName, String.valueOf(newValue)); 1039 return "true".equalsIgnoreCase(oldValue); 1040 } 1041 1042 /** 1043 * Indicates whether all threads created by the Directory Server 1044 * should be created as daemon threads. 1045 * 1046 * @return {@code true} if all threads created by the Directory 1047 * Server should be created as daemon threads, or 1048 * {@code false} if not. 1049 */ 1050 public boolean forceDaemonThreads() 1051 { 1052 return isPropertyTrue(PROPERTY_FORCE_DAEMON_THREADS); 1053 } 1054 1055 1056 1057 /** 1058 * Specifies whether all threads created by the Directory Server 1059 * should be created as daemon threads. 1060 * 1061 * @param forceDaemonThreads Indicates whether all threads created 1062 * by the Directory Server should be 1063 * created as daemon threads. 1064 * 1065 * @return The previous setting for this configuration option. If 1066 * no previous value was specified, then {@code false} will 1067 * be returned. 1068 * 1069 * @throws InitializationException If the Directory Server is 1070 * already running. 1071 */ 1072 public boolean setForceDaemonThreads(boolean forceDaemonThreads) 1073 throws InitializationException 1074 { 1075 return setBooleanProperty(PROPERTY_FORCE_DAEMON_THREADS, 1076 forceDaemonThreads); 1077 } 1078 1079 1080 1081 /** 1082 * Indicates whether the Directory Server should be allowed to use 1083 * the {@code Runtime.exec()} method to be able to launch external 1084 * commands on the underlying system. 1085 * 1086 * @return {@code true} if the Directory Server should be allowed 1087 * to use {@code Runtime.exec()}, or {@code false} if not. 1088 */ 1089 public boolean disableExec() 1090 { 1091 return isPropertyTrue(PROPERTY_DISABLE_EXEC); 1092 } 1093 1094 1095 1096 /** 1097 * Specifies whether the Directory Server should be allowed to use 1098 * the {@code Runtime.exec()} method to be able to launch external 1099 * commands on the underlying system. 1100 * 1101 * @param disableExec Indicates whether the Directory Server 1102 * should be allowed to launch external 1103 * commands on the underlying system. 1104 * 1105 * @return The previous setting for this configuration option. If 1106 * no previous value was specified, then {@code false} will 1107 * be returned. 1108 * 1109 * @throws InitializationException If the Directory Server is 1110 * already running. 1111 */ 1112 public boolean setDisableExec(boolean disableExec) 1113 throws InitializationException 1114 { 1115 return setBooleanProperty(PROPERTY_DISABLE_EXEC, disableExec); 1116 } 1117 1118 1119 1120 /** Throws an exception if server is running and it is not allowed. */ 1121 private void checkServerIsRunning() throws InitializationException 1122 { 1123 if (checkIfServerIsRunning && DirectoryServer.isRunning()) 1124 { 1125 throw new InitializationException( 1126 ERR_DIRCFG_SERVER_ALREADY_RUNNING.get()); 1127 } 1128 } 1129}