001/* 002 * Copyright 2007-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 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 Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk; 022 023 024 025import java.lang.reflect.Method; 026import java.util.Arrays; 027import java.util.Collections; 028import java.util.EnumMap; 029import java.util.HashMap; 030import java.util.Map; 031import java.util.logging.Level; 032 033import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest; 034import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; 035import com.unboundid.ldap.sdk.extensions.WhoAmIExtendedRequest; 036import com.unboundid.ldap.sdk.unboundidds.extensions. 037 DeregisterYubiKeyOTPDeviceExtendedRequest; 038import com.unboundid.ldap.sdk.unboundidds.extensions. 039 EndAdministrativeSessionExtendedRequest; 040import com.unboundid.ldap.sdk.unboundidds.extensions. 041 GenerateTOTPSharedSecretExtendedRequest; 042import com.unboundid.ldap.sdk.unboundidds.extensions. 043 GetConnectionIDExtendedRequest; 044import com.unboundid.ldap.sdk.unboundidds.extensions. 045 GetPasswordQualityRequirementsExtendedRequest; 046import com.unboundid.ldap.sdk.unboundidds.extensions. 047 PasswordPolicyStateExtendedRequest; 048import com.unboundid.ldap.sdk.unboundidds.extensions. 049 RegisterYubiKeyOTPDeviceExtendedRequest; 050import com.unboundid.ldap.sdk.unboundidds.extensions. 051 RevokeTOTPSharedSecretExtendedRequest; 052import com.unboundid.ldap.sdk.unboundidds.extensions. 053 StartAdministrativeSessionExtendedRequest; 054import com.unboundid.ldap.sdk.unboundidds.extensions. 055 ValidateTOTPPasswordExtendedRequest; 056import com.unboundid.util.Debug; 057import com.unboundid.util.DebugType; 058import com.unboundid.util.Mutable; 059import com.unboundid.util.StaticUtils; 060import com.unboundid.util.ThreadSafety; 061import com.unboundid.util.ThreadSafetyLevel; 062import com.unboundid.util.Validator; 063import com.unboundid.util.ssl.SSLSocketVerifier; 064import com.unboundid.util.ssl.TrustAllSSLSocketVerifier; 065 066 067 068/** 069 * This class provides a data structure that may be used to configure a number 070 * of connection-related properties. Elements included in the set of connection 071 * options include: 072 * <UL> 073 * <LI>A flag that indicates whether the SDK should attempt to automatically 074 * re-establish a connection if it is unexpectedly closed. By default, 075 * it will not attempt to do so.</LI> 076 * <LI>A flag that indicates whether simple bind attempts that contain a 077 * non-empty DN will be required to have a non-empty password. By 078 * default, a password will be required in such cases.</LI> 079 * <LI>A flag that indicates whether to automatically attempt to follow any 080 * referrals that may be returned by the server. By default, it will not 081 * automatically attempt to follow referrals.</LI> 082 * <LI>A referral hop limit, which indicates the maximum number of hops that 083 * the connection may take when trying to follow a referral. The default 084 * referral hop limit is five.</LI> 085 * <LI>The referral connector that should be used to create and optionally 086 * authenticate connections used to follow referrals encountered during 087 * processing. By default, referral connections will use the same socket 088 * factory and bind request as the client connection on which the referral 089 * was received.</LI> 090 * <LI>A flag that indicates whether to use the SO_KEEPALIVE socket option to 091 * attempt to more quickly detect when idle TCP connections have been lost 092 * or to prevent them from being unexpectedly closed by intermediate 093 * network hardware. By default, the SO_KEEPALIVE socket option will be 094 * used.</LI> 095 * <LI>A flag that indicates whether to use the SO_LINGER socket option to 096 * indicate how long a connection should linger after it has been closed, 097 * and a value that specifies the length of time that it should linger. 098 * By default, the SO_LINGER option will be used with a timeout of 5 099 * seconds.</LI> 100 * <LI>A flag that indicates whether to use the SO_REUSEADDR socket option to 101 * indicate that a socket in a TIME_WAIT state may be reused. By default, 102 * the SO_REUSEADDR socket option will be used.</LI> 103 * <LI>A flag that indicates whether to operate in synchronous mode, in which 104 * connections may exhibit better performance and will not require a 105 * separate reader thread, but will not allow multiple concurrent 106 * operations to be used on the same connection.</LI> 107 * <LI>A flag that indicates whether to use the TCP_NODELAY socket option to 108 * indicate that any data written to the socket will be sent immediately 109 * rather than delaying for a short amount of time to see if any more data 110 * is to be sent that could potentially be included in the same packet. 111 * By default, the TCP_NODELAY socket option will be used.</LI> 112 * <LI>A value that specifies the maximum length of time in milliseconds that 113 * an attempt to establish a connection should be allowed to block before 114 * failing. By default, a timeout of 10,000 milliseconds (10 seconds) 115 * will be used.</LI> 116 * <LI>A value that specifies the default timeout in milliseconds that the SDK 117 * should wait for a response from the server before failing. This can be 118 * defined on a per-operation-type basis, with a default of 300,000 119 * milliseconds (5 minutes) for search and extended operations, and a 120 * default timeout of 30,000 milliseconds (30 seconds) for all other types 121 * of operations. Further, the extended operation timeout can be 122 * customized on a per-operation-type basis, and a number of extended 123 * operation types have been configured with a 30,000 millisecond timeout 124 * by default. Individual requests can also be configured with their own 125 * response timeouts, and if provided, that timeout will override the 126 * default timeout from the connection options.</LI> 127 * <LI>A flag that indicates whether to attempt to abandon any request for 128 * which no response is received after waiting for the maximum response 129 * timeout. By default, no abandon request will be sent.</LI> 130 * <LI>A value which specifies the largest LDAP message size that the SDK will 131 * be willing to read from the directory server. By default, the SDK will 132 * not allow responses larger than 20,971,520 bytes (20MB). If it 133 * encounters a message that may be larger than the maximum allowed 134 * message size, then the SDK will terminate the connection to the 135 * server.</LI> 136 * <LI>The {@link DisconnectHandler} that should be used to receive 137 * notification if connection is disconnected for any reason. By default, 138 * no {@code DisconnectHandler} will be used.</LI> 139 * <LI>The {@link UnsolicitedNotificationHandler} that should be used to 140 * receive notification about any unsolicited notifications returned by 141 * the server. By default, no {@code UnsolicitedNotificationHandler} will 142 * be used.</LI> 143 * <LI>A flag that indicates whether to capture a thread stack trace whenever 144 * a new connection is established. Capturing a thread stack trace when 145 * establishing a connection may be marginally expensive, but can be 146 * useful for debugging certain kinds of problems like leaked connections 147 * (connections that are established but never explicitly closed). By 148 * default, connect stack traces will not be captured.</LI> 149 * <LI>A flag that indicates whether connections should try to retrieve schema 150 * information from the server, which may be used to better determine 151 * which matching rules should be used when comparing attribute values. 152 * By default, server schema information will not be retrieved.</LI> 153 * <LI>The size of the socket receive buffer, which may be used for 154 * temporarily holding data received from the directory server until it 155 * can be read and processed by the LDAP SDK. By default, the receive 156 * buffer size will be automatically determined by the JVM based on the 157 * underlying system settings.</LI> 158 * <LI>The size of the socket send buffer, which may be used for temporarily 159 * holding data to be sent to the directory server until it can actually 160 * be transmitted over the network. By default, the send buffer size will 161 * be automatically determined by the JVM based on the underlying system 162 * settings.</LI> 163 * <LI>A flag which indicates whether to allow a single socket factory instance 164 * (which may be shared across multiple connections) to be used to create 165 * multiple concurrent connections. This offers better and more 166 * predictable performance on some JVM implementations (especially when 167 * connection attempts fail as a result of a connection timeout), but some 168 * JVMs are known to use non-threadsafe socket factory implementations and 169 * may fail from concurrent use (for example, at least some IBM JVMs 170 * exhibit this behavior). By default, Sun/Oracle JVMs will allow 171 * concurrent socket factory use, but JVMs from other vendors will use 172 * synchronization to ensure that a socket factory will only be allowed to 173 * create one connection at a time.</LI> 174 * <LI>A class that may be used to perform additional verification (e.g., 175 * hostname validation) for any {@code SSLSocket} instances created. By 176 * default, no special verification will be performed.</LI> 177 * </UL> 178 */ 179@Mutable() 180@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 181public final class LDAPConnectionOptions 182{ 183 /** 184 * The prefix that will be used in conjunction with all system properties. 185 */ 186 private static final String PROPERTY_PREFIX = 187 LDAPConnectionOptions.class.getName() + '.'; 188 189 190 191 /** 192 * The name of a system property that can be used to specify the initial 193 * default value for the "abandon on timeout" behavior. If this property is 194 * set at the time that this class is loaded, then its value must be either 195 * "true" or "false". If this property is not set, then a default value of 196 * "false" will be assumed. 197 * <BR><BR> 198 * The full name for this system property is 199 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultAbandonTimeout". 200 */ 201 public static final String PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT = 202 PROPERTY_PREFIX + "defaultAbandonOnTimeout"; 203 204 205 206 /** 207 * The default value for the setting that controls whether to automatically 208 * attempt to abandon any request for which no response is received within the 209 * maximum response timeout. If the 210 * {@link #PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT} system property is set at the 211 * time this class is loaded, then its value will be used. Otherwise, a 212 * default of {@code false} will be used. 213 */ 214 private static final boolean DEFAULT_ABANDON_ON_TIMEOUT = 215 getSystemProperty(PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT, false); 216 217 218 219 /** 220 * The default value ({@code false}) for the setting that controls whether to 221 * automatically attempt to reconnect if a connection is unexpectedly lost. 222 */ 223 private static final boolean DEFAULT_AUTO_RECONNECT = false; 224 225 226 227 /** 228 * The name of a system property that can be used to specify the initial 229 * default value for the "bind with DN requires password" behavior. If this 230 * property is set at the time that this class is loaded, then its value must 231 * be either "true" or "false". If this property is not set, then a default 232 * value of "true" will be assumed. 233 * <BR><BR> 234 * The full name for this system property is 235 * "com.unboundid.ldap.sdk.LDAPConnectionOptions. 236 * defaultBindWithDNRequiresPassword". 237 */ 238 public static final String PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = 239 PROPERTY_PREFIX + "defaultBindWithDNRequiresPassword"; 240 241 242 243 /** 244 * The default value for the setting that controls whether simple bind 245 * requests with a DN will also be required to contain a password. If the 246 * {@link #PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD} system property is 247 * set at the time this class is loaded, then its value will be used. 248 * Otherwise, a default of {@code true} will be used. 249 */ 250 private static final boolean DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = 251 getSystemProperty(PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD, true); 252 253 254 255 /** 256 * The name of a system property that can be used to specify the initial 257 * default value for the "capture connect stack trace" behavior. If this 258 * property is set at the time that this class is loaded, then its value must 259 * be either "true" or "false". If this property is not set, then a default 260 * value of "false" will be assumed. 261 * <BR><BR> 262 * The full name for this system property is "com.unboundid.ldap.sdk. 263 * LDAPConnectionOptions.defaultCaptureConnectStackTrace". 264 */ 265 public static final String PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE = 266 PROPERTY_PREFIX + "defaultCaptureConnectStackTrace"; 267 268 269 270 /** 271 * The default value for the setting that controls whether to capture a thread 272 * stack trace whenever an attempt is made to establish a connection. If the 273 * {@link #PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE} system property is 274 * set at the time this class is loaded, then its value will be used. 275 * Otherwise, a default of {@code false} will be used. 276 */ 277 private static final boolean DEFAULT_CAPTURE_CONNECT_STACK_TRACE = 278 getSystemProperty(PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE, false); 279 280 281 282 /** 283 * The name of a system property that can be used to specify the initial 284 * default value for the "follow referrals" behavior. If this property is set 285 * at the time that this class is loaded, then its value must be either 286 * "true" or "false". If this property is not set, then a default value of 287 * "false" will be assumed. 288 * <BR><BR> 289 * The full name for this system property is 290 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultFollowReferrals". 291 */ 292 public static final String PROPERTY_DEFAULT_FOLLOW_REFERRALS = 293 PROPERTY_PREFIX + "defaultFollowReferrals"; 294 295 296 297 /** 298 * The default value for the setting that controls whether to attempt to 299 * automatically follow referrals. If the 300 * {@link #PROPERTY_DEFAULT_FOLLOW_REFERRALS} system property is set at the 301 * time this class is loaded, then its value will be used. Otherwise, a 302 * default of {@code false} will be used. 303 */ 304 private static final boolean DEFAULT_FOLLOW_REFERRALS = 305 getSystemProperty(PROPERTY_DEFAULT_FOLLOW_REFERRALS, false); 306 307 308 309 /** 310 * The name of a system property that can be used to specify the maximum 311 * number of hops to make when following a referral. If this property is set 312 * at the time that this class is loaded, then its value must be parseable as 313 * an integer. If this property is not set, then a default value of "5" will 314 * be assumed. 315 * <BR><BR> 316 * The full name for this system property is 317 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultReferralHopLimit". 318 */ 319 public static final String PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT = 320 PROPERTY_PREFIX + "defaultReferralHopLimit"; 321 322 323 324 /** 325 * The default value for the setting that controls the referral hop limit. If 326 * the {@link #PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT} system property is set at 327 * the time this class is loaded, then its value will be used. Otherwise, a 328 * default value of 5 will be used. 329 */ 330 private static final int DEFAULT_REFERRAL_HOP_LIMIT = 331 getSystemProperty(PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT, 5); 332 333 334 335 /** 336 * The name of a system property that can be used to specify the initial 337 * default value for the "use schema" behavior. If this property is set at 338 * the time that this class is loaded, then its value must be either "true" or 339 * "false". If this property is not set, then a default value of "false" will 340 * be assumed. 341 * <BR><BR> 342 * The full name for this system property is 343 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseSchema". 344 */ 345 public static final String PROPERTY_DEFAULT_USE_SCHEMA = 346 PROPERTY_PREFIX + "defaultUseSchema"; 347 348 349 350 /** 351 * The default value for the setting that controls whether to use schema when 352 * reading data from the server. If the {@link #PROPERTY_DEFAULT_USE_SCHEMA} 353 * system property is set at the time this class is loaded, then its value 354 * will be used. Otherwise, a default value of {@code false} will be used. 355 */ 356 private static final boolean DEFAULT_USE_SCHEMA = 357 getSystemProperty(PROPERTY_DEFAULT_USE_SCHEMA, false); 358 359 360 361 /** 362 * The name of a system property that can be used to specify the initial 363 * default value for the "use pooled schema" behavior. If this property is 364 * set at the time that this class is loaded, then its value must be either 365 * "true" or "false". If this property is not set, then a default value of 366 * "false" will be assumed. 367 * <BR><BR> 368 * The full name for this system property is 369 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUsePooledSchema". 370 */ 371 public static final String PROPERTY_DEFAULT_USE_POOLED_SCHEMA = 372 PROPERTY_PREFIX + "defaultUsePooledSchema"; 373 374 375 376 /** 377 * The default value for the setting that controls whether all connections in 378 * a connection pool should use the same cached schema object. If the 379 * {@link #PROPERTY_DEFAULT_USE_POOLED_SCHEMA} system property is set at the 380 * time this class is loaded, then its value will be used. Otherwise, a 381 * default of {@code false} will be used. 382 */ 383 private static final boolean DEFAULT_USE_POOLED_SCHEMA = 384 getSystemProperty(PROPERTY_DEFAULT_USE_POOLED_SCHEMA, false); 385 386 387 388 /** 389 * The name of a system property that can be used to specify the initial 390 * default value for the pooled schema timeout, in milliseconds. If this 391 * property is set at the time that this class is loaded, then its value must 392 * be parseable as an integer. If this property is not set, then a default 393 * value of "3600000" (3,600,000 milliseconds, or 1 hour) will be assumed. 394 * <BR><BR> 395 * The full name for this system property is "com.unboundid.ldap.sdk. 396 * LDAPConnectionOptions.defaultPooledSchemaTimeoutMillis". 397 */ 398 public static final String PROPERTY_DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 399 PROPERTY_PREFIX + "defaultPooledSchemaTimeoutMillis"; 400 401 402 403 /** 404 * The default value for the setting that controls the default pooled schema 405 * timeout. If the {@link #PROPERTY_DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS} 406 * system property is set at the time this class is loaded, then its value 407 * will be used. Otherwise, a default of 3,600,000 milliseconds (1 hour) will 408 * be used. 409 */ 410 private static final long DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 3_600_000L; 411 412 413 414 /** 415 * The name of a system property that can be used to specify the initial 416 * default value for the "use keepalive" behavior. If this property is set at 417 * the time that this class is loaded, then its value must be either "true" or 418 * "false". If this property is not set, then a default value of "true" will 419 * be assumed. 420 * <BR><BR> 421 * The full name for this system property is 422 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseKeepalive". 423 */ 424 public static final String PROPERTY_DEFAULT_USE_KEEPALIVE = 425 PROPERTY_PREFIX + "defaultUseKeepalive"; 426 427 428 429 /** 430 * The default value for the setting that controls whether to use the 431 * {@code SO_KEEPALIVE} socket option. If the 432 * {@link #PROPERTY_DEFAULT_USE_KEEPALIVE} system property is set at the time 433 * this class is loaded, then its value will be used. Otherwise, a default of 434 * {@code true} will be used. 435 */ 436 private static final boolean DEFAULT_USE_KEEPALIVE = 437 getSystemProperty(PROPERTY_DEFAULT_USE_KEEPALIVE, true); 438 439 440 441 /** 442 * The name of a system property that can be used to specify the initial 443 * default value for the "use linger" behavior. If this property is set at 444 * the time that this class is loaded, then its value must be either "true" or 445 * "false". If this property is not set, then a default value of "true" will 446 * be assumed. 447 * <BR><BR> 448 * The full name for this system property is 449 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseLinger". 450 */ 451 public static final String PROPERTY_DEFAULT_USE_LINGER = 452 PROPERTY_PREFIX + "defaultUseLinger"; 453 454 455 456 /** 457 * The default value for the setting that controls whether to use the 458 * {@code SO_LINGER} socket option. If the 459 * {@link #PROPERTY_DEFAULT_USE_LINGER} system property is set at the time 460 * this class is loaded, then its value will be used. Otherwise, a default of 461 * {@code true} will be used. 462 */ 463 private static final boolean DEFAULT_USE_LINGER = 464 getSystemProperty(PROPERTY_DEFAULT_USE_LINGER, true); 465 466 467 468 /** 469 * The name of a system property that can be used to specify the initial 470 * default value for the linger timeout, in seconds. If this property is set 471 * at the time that this class is loaded, then its value must be parseable as 472 * an integer. If this property is not set, then a default value of "5" (5 473 * seconds) will be assumed. 474 * <BR><BR> 475 * The full name for this system property is 476 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultLingerTimeoutSeconds". 477 */ 478 public static final String PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS = 479 PROPERTY_PREFIX + "defaultLingerTimeoutSeconds"; 480 481 482 483 /** 484 * The default value for the setting that controls the timeout in seconds that 485 * will be used with the {@code SO_LINGER} socket option. If the 486 * {@link #PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS} property is set at the 487 * time this class is loaded, then its value will be used. Otherwise, a 488 * default linger timeout of 5 seconds will be used. 489 */ 490 private static final int DEFAULT_LINGER_TIMEOUT_SECONDS = 491 getSystemProperty(PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS, 5); 492 493 494 495 /** 496 * The name of a system property that can be used to specify the initial 497 * default value for the "use reuse address" behavior. If this property is 498 * set at the time that this class is loaded, then its value must be either 499 * "true" or "false". If this property is not set, then a default value of 500 * "true" will be assumed. 501 * <BR><BR> 502 * The full name for this system property is 503 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseReuseAddress". 504 */ 505 public static final String PROPERTY_DEFAULT_USE_REUSE_ADDRESS = 506 PROPERTY_PREFIX + "defaultUseReuseAddress"; 507 508 509 510 /** 511 * The default value for the setting that controls whether to use the 512 * {@code SO_REUSEADDR} socket option. If the 513 * {@link #PROPERTY_DEFAULT_USE_REUSE_ADDRESS} system property is set at the 514 * time this class is loaded, then its value will be used. Otherwise, a 515 * default value of {@code true} will be used. 516 */ 517 private static final boolean DEFAULT_USE_REUSE_ADDRESS = 518 getSystemProperty(PROPERTY_DEFAULT_USE_REUSE_ADDRESS, true); 519 520 521 522 /** 523 * The name of a system property that can be used to specify the initial 524 * default value for the "use synchronous mode" behavior. If this property is 525 * set at the time that this class is loaded, then its value must be either 526 * "true" or "false". If this property is not set, then a default value of 527 * "false" will be assumed. 528 * <BR><BR> 529 * The full name for this system property is 530 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseSynchronousMode". 531 */ 532 public static final String PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE = 533 PROPERTY_PREFIX + "defaultUseSynchronousMode"; 534 535 536 537 /** 538 * The default value for the setting that controls whether to operate in 539 * synchronous mode, in which only a single outstanding operation may be in 540 * progress on an associated connection at any given time. If the 541 * {@link #PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE} system property is set at 542 * the time this class is loaded, then its value will be used. Otherwise, a 543 * default value of {@code false} will be used. 544 */ 545 private static final boolean DEFAULT_USE_SYNCHRONOUS_MODE = 546 getSystemProperty(PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE, false); 547 548 549 550 /** 551 * The name of a system property that can be used to specify the initial 552 * default value for the "use TCP nodelay" behavior. If this property is set 553 * at the time that this class is loaded, then its value must be either "true" 554 * or "false". If this property is not set, then a default value of "true" 555 * will be assumed. 556 * <BR><BR> 557 * The full name for this system property is 558 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseTCPNoDelay". 559 */ 560 public static final String PROPERTY_DEFAULT_USE_TCP_NODELAY = 561 PROPERTY_PREFIX + "defaultUseTCPNoDelay"; 562 563 564 565 /** 566 * The default value for the setting that controls whether to use the 567 * {@code TCP_NODELAY} socket option. If the 568 * {@link #PROPERTY_DEFAULT_USE_TCP_NODELAY} system property is set at the 569 * time this class is loaded, then its value will be used. Otherwise, a 570 * default value of {@code true} will be used. 571 */ 572 private static final boolean DEFAULT_USE_TCP_NODELAY = 573 getSystemProperty(PROPERTY_DEFAULT_USE_TCP_NODELAY, true); 574 575 576 577 /** 578 * The name of a system property that can be used to specify the initial 579 * default connect timeout, in milliseconds. If this property is set at the 580 * time that this class is loaded, then its value must be parseable as an 581 * integer. If this property is not set then a default value of "10000" 582 * (10,000 milliseconds, or ten seconds) will be assumed. 583 * <BR><BR> 584 * The full name for this system property is 585 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultConnectTimeoutMillis". 586 */ 587 public static final String PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS = 588 PROPERTY_PREFIX + "defaultConnectTimeoutMillis"; 589 590 591 592 /** 593 * The default value for the setting that controls the timeout in milliseconds 594 * when trying to establish a new connection. If the 595 * {@link #PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS} system property is set at 596 * the time this class is loaded, then its value will be used. Otherwise, a 597 * default of 10,000 milliseconds (10 seconds) will be used. 598 */ 599 private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 600 getSystemProperty(PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS, 10_000); 601 602 603 604 /** 605 * The name of a system property that can be used to specify the initial 606 * default value for the maximum message size, in bytes. If this property is 607 * set at the time that this class is loaded, then its value must be parseable 608 * as an integer. If this property is not set, then a default value of 609 * "20971520" (20 megabytes) will be assumed. 610 * <BR><BR> 611 * The full name for this system property is 612 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultMaxMessageSizeBytes". 613 */ 614 public static final String PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES = 615 PROPERTY_PREFIX + "defaultMaxMessageSizeBytes"; 616 617 618 619 /** 620 * The default value for the setting that controls the maximum LDAP message 621 * size in bytes that will be allowed when reading data from a directory 622 * server. If the {@link #PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES} system 623 * property is set at the time this class is loaded, then its value will be 624 * used. Otherwise, a default value of 20,971,520 bytes (20 megabytes) will 625 * be used. 626 */ 627 private static final int DEFAULT_MAX_MESSAGE_SIZE_BYTES = 628 getSystemProperty(PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES, 20_971_520); 629 630 631 632 /** 633 * The name of a system property that can be used to specify the initial 634 * default value for the receive buffer size, in bytes. If this property is 635 * set at the time that this class is loaded, then its value must be parseable 636 * as an integer. If this property is not set, then a default value of "0" 637 * (indicating that the JVM's default receive buffer size) will be assumed. 638 * <BR><BR> 639 * The full name for this system property is "com.unboundid.ldap.sdk. 640 * LDAPConnectionOptions.defaultReceiveBufferSizeBytes". 641 */ 642 public static final String PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES = 643 PROPERTY_PREFIX + "defaultReceiveBufferSizeBytes"; 644 645 646 647 /** 648 * The default size, in bytes, to use for the receive buffer. If the 649 * {@link #PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES} system property is set 650 * at the time this class is loaded, then its value will be used. Otherwise, 651 * a default value of 0 will be used to indicate that the JVM's default 652 * receive buffer size should be used. 653 */ 654 private static final int DEFAULT_RECEIVE_BUFFER_SIZE_BYTES = 655 getSystemProperty(PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES, 0); 656 657 658 659 /** 660 * The name of a system property that can be used to specify the initial 661 * default value for the send buffer size, in bytes. If this property is set 662 * at the time that this class is loaded, then its value must be parseable as 663 * an integer. If this property is not set, then a default value of "0" 664 * (indicating that the JVM's default send buffer size) will be assumed. 665 * <BR><BR> 666 * The full name for this system property is 667 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultSendBufferSizeBytes". 668 */ 669 public static final String PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES = 670 PROPERTY_PREFIX + "defaultSendBufferSizeBytes"; 671 672 673 674 /** 675 * The default size, in bytes, to use for the send buffer. If the 676 * {@link #PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES} system property is set at 677 * the time this class is loaded, then its value will be used. Otherwise, a 678 * default value of 0 will be used to indicate that the JVM's default send 679 * buffer size should be used. 680 */ 681 private static final int DEFAULT_SEND_BUFFER_SIZE_BYTES = 682 getSystemProperty(PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES, 0); 683 684 685 686 /** 687 * The name of a system property that can be used to specify the initial 688 * default value for response timeouts, in milliseconds, for all types of 689 * operations. If this property is set at the time that this class is loaded, 690 * then its value must be parseable as an integer, and that value will 691 * override the values of any operation-specific properties. If this property 692 * is not set, then a default value of "300000" (300,000 milliseconds, or 693 * 5 minutes) will be assumed, but that may be overridden by 694 * operation-specific properties. 695 * <BR><BR> 696 * The full name for this system property is "com.unboundid.ldap.sdk. 697 * LDAPConnectionOptions.defaultResponseTimeoutMillis". 698 */ 699 public static final String PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS = 700 PROPERTY_PREFIX + "defaultResponseTimeoutMillis"; 701 702 703 704 /** 705 * The name of a system property that can be used to specify the initial 706 * default value for response timeouts, in milliseconds, for add operations. 707 * If this property is set at the time that this class is loaded, then 708 * its value must be parseable as an integer. It will only be used if the 709 * {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system property is not 710 * set, as that property will override this one. If neither of those 711 * properties is set, then a default value of "30000" (30,000 milliseconds, or 712 * 30 seconds) will be assumed. 713 * <BR><BR> 714 * The full name for this system property is "com.unboundid.ldap.sdk. 715 * LDAPConnectionOptions.defaultAddResponseTimeoutMillis". 716 */ 717 public static final String PROPERTY_DEFAULT_ADD_RESPONSE_TIMEOUT_MILLIS = 718 PROPERTY_PREFIX + "defaultAddResponseTimeoutMillis"; 719 720 721 722 /** 723 * The name of a system property that can be used to specify the initial 724 * default value for response timeouts, in milliseconds, for bind operations. 725 * If this property is set at the time that this class is loaded, then 726 * its value must be parseable as an integer. It will only be used if the 727 * {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system property is not 728 * set, as that property will override this one. If neither of those 729 * properties is set, then a default value of "30000" (30,000 milliseconds, or 730 * 30 seconds) will be assumed. 731 * <BR><BR> 732 * The full name for this system property is "com.unboundid.ldap.sdk. 733 * LDAPConnectionOptions.defaultBindResponseTimeoutMillis". 734 */ 735 public static final String PROPERTY_DEFAULT_BIND_RESPONSE_TIMEOUT_MILLIS = 736 PROPERTY_PREFIX + "defaultBindResponseTimeoutMillis"; 737 738 739 740 /** 741 * The name of a system property that can be used to specify the initial 742 * default value for response timeouts, in milliseconds, for compare 743 * operations. If this property is set at the time that this class is 744 * loaded, then its value must be parseable as an integer. It will only be 745 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 746 * property is not set, as that property will override this one. If neither 747 * of those properties is set, then a default value of "30000" (30,000 748 * milliseconds, or 30 seconds) will be assumed. 749 * <BR><BR> 750 * The full name for this system property is "com.unboundid.ldap.sdk. 751 * LDAPConnectionOptions.defaultCompareResponseTimeoutMillis". 752 */ 753 public static final String PROPERTY_DEFAULT_COMPARE_RESPONSE_TIMEOUT_MILLIS = 754 PROPERTY_PREFIX + "defaultCompareResponseTimeoutMillis"; 755 756 757 758 /** 759 * The name of a system property that can be used to specify the initial 760 * default value for response timeouts, in milliseconds, for delete 761 * operations. If this property is set at the time that this class is 762 * loaded, then its value must be parseable as an integer. It will only be 763 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 764 * property is not set, as that property will override this one. If neither 765 * of those properties is set, then a default value of "30000" (30,000 766 * milliseconds, or 30 seconds) will be assumed. 767 * <BR><BR> 768 * The full name for this system property is "com.unboundid.ldap.sdk. 769 * LDAPConnectionOptions.defaultDeleteResponseTimeoutMillis". 770 */ 771 public static final String PROPERTY_DEFAULT_DELETE_RESPONSE_TIMEOUT_MILLIS = 772 PROPERTY_PREFIX + "defaultDeleteResponseTimeoutMillis"; 773 774 775 776 /** 777 * The name of a system property that can be used to specify the initial 778 * default value for response timeouts, in milliseconds, for extended 779 * operations. If this property is set at the time that this class is 780 * loaded, then its value must be parseable as an integer. It will only be 781 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 782 * property is not set, as that property will override this one. If neither 783 * of those properties is set, then a default value of "300000" (300,000 784 * milliseconds, or 5 minutes) will be assumed. 785 * <BR><BR> 786 * The full name for this system property is "com.unboundid.ldap.sdk. 787 * LDAPConnectionOptions.defaultExtendedResponseTimeoutMillis". 788 * <BR><BR> 789 * Note that different timeouts may be set for specific types using a system 790 * property with this name immediately followed by a period and the request 791 * OID for the desired extended operation type. For example, the system 792 * property named "com.unboundid.ldap.sdk.LDAPConnectionOptions. 793 * defaultExtendedResponseTimeoutMillis.1.3.6.1.4.1.1466.20037" can be used to 794 * set a default response timeout for StartTLS extended operations. 795 * <BR><BR> 796 * If neither the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} nor the 797 * {@code PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS} property is set, 798 * then the following standard extended operation types will have a default 799 * timeout of 30,000 milliseconds (30 seconds) instead of 300,000 milliseconds 800 * (5 minutes), unless a property is defined to override the timeout for that 801 * specific type of extended operation: 802 * <BR> 803 * <UL> 804 * <LI>Password Modify (1.3.6.1.4.1.4203.1.11.1)</LI> 805 * <LI>StartTLS (1.3.6.1.4.1.1466.20037)</LI> 806 * <LI>Who Am I? (1.3.6.1.4.1.4203.1.11.3)</LI> 807 * </UL> 808 * <BR> 809 * The same will also be true for the following extended operations specific 810 * to the UnboundID/Ping Identity Directory Server: 811 * <BR> 812 * <UL> 813 * <LI>Deregister YubiKey OTP Device (1.3.6.1.4.1.30221.2.6.55)</LI> 814 * <LI>End Administrative Session (1.3.6.1.4.1.30221.2.6.14)</LI> 815 * <LI>Generate TOTP Shared Secret (1.3.6.1.4.1.30221.2.6.56)</LI> 816 * <LI>Get Connection ID (1.3.6.1.4.1.30221.1.6.2)</LI> 817 * <LI>Get Password Quality Requirements (1.3.6.1.4.1.30221.2.6.43)</LI> 818 * <LI>Password Policy State (1.3.6.1.4.1.30221.1.6.1)</LI> 819 * <LI>Register YubiKey OTP Device (1.3.6.1.4.1.30221.2.6.54)</LI> 820 * <LI>Revoke TOTP Shared Secret (1.3.6.1.4.1.30221.2.6.58)</LI> 821 * <LI>Start Administrative Session (1.3.6.1.4.1.30221.2.6.13)</LI> 822 * <LI>Validate TOTP Password (1.3.6.1.4.1.30221.2.6.15)</LI> 823 * </UL> 824 */ 825 public static final String PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS = 826 PROPERTY_PREFIX + "defaultExtendedResponseTimeoutMillis"; 827 828 829 830 /** 831 * The name of a system property that can be used to specify the initial 832 * default value for response timeouts, in milliseconds, for modify 833 * operations. If this property is set at the time that this class is 834 * loaded, then its value must be parseable as an integer. It will only be 835 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 836 * property is not set, as that property will override this one. If neither 837 * of those properties is set, then a default value of "30000" (30,000 838 * milliseconds, or 30 seconds) will be assumed. 839 * <BR><BR> 840 * The full name for this system property is "com.unboundid.ldap.sdk. 841 * LDAPConnectionOptions.defaultModifyResponseTimeoutMillis". 842 */ 843 public static final String PROPERTY_DEFAULT_MODIFY_RESPONSE_TIMEOUT_MILLIS = 844 PROPERTY_PREFIX + "defaultModifyResponseTimeoutMillis"; 845 846 847 848 /** 849 * The name of a system property that can be used to specify the initial 850 * default value for response timeouts, in milliseconds, for modify DN 851 * operations. If this property is set at the time that this class is 852 * loaded, then its value must be parseable as an integer. It will only be 853 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 854 * property is not set, as that property will override this one. If neither 855 * of those properties is set, then a default value of "30000" (30,000 856 * milliseconds, or 30 seconds) will be assumed. 857 * <BR><BR> 858 * The full name for this system property is "com.unboundid.ldap.sdk. 859 * LDAPConnectionOptions.defaultModifyDNResponseTimeoutMillis". 860 */ 861 public static final String 862 PROPERTY_DEFAULT_MODIFY_DN_RESPONSE_TIMEOUT_MILLIS = 863 PROPERTY_PREFIX + "defaultModifyDNResponseTimeoutMillis"; 864 865 866 867 /** 868 * The name of a system property that can be used to specify the initial 869 * default value for response timeouts, in milliseconds, for search 870 * operations. If this property is set at the time that this class is 871 * loaded, then its value must be parseable as an integer. It will only be 872 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 873 * property is not set, as that property will override this one. If neither 874 * of those properties is set, then a default value of "300000" (300,000 875 * milliseconds, or 5 minutes) will be assumed. 876 * <BR><BR> 877 * The full name for this system property is "com.unboundid.ldap.sdk. 878 * LDAPConnectionOptions.defaultSearchResponseTimeoutMillis". 879 */ 880 public static final String PROPERTY_DEFAULT_SEARCH_RESPONSE_TIMEOUT_MILLIS = 881 PROPERTY_PREFIX + "defaultSearchResponseTimeoutMillis"; 882 883 884 885 /** 886 * The default value for the setting that controls the default response 887 * timeout, in milliseconds, for all types of operations. 888 */ 889 private static final long DEFAULT_RESPONSE_TIMEOUT_MILLIS; 890 891 892 893 /** 894 * A map that holds the default values for the settings that control the 895 * default response timeouts, in milliseconds, for each type of operation. 896 */ 897 private static final Map<OperationType,Long> 898 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE; 899 900 901 902 /** 903 * A map that holds the default values for the settings that control the 904 * default response timeouts, in milliseconds, for specific types of extended 905 * operations. 906 */ 907 private static final Map<String,Long> 908 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE; 909 910 911 912 /** 913 * The default name resolver that will be used to resolve host names to IP 914 * addresses. 915 */ 916 public static final NameResolver DEFAULT_NAME_RESOLVER; 917 918 919 920 static 921 { 922 // Get the default response timeout for all types of operations. 923 Long allOpsTimeout = null; 924 final EnumMap<OperationType,Long> timeoutsByOpType = 925 new EnumMap<>(OperationType.class); 926 final HashMap<String,Long> timeoutsByExtOpType = 927 new HashMap<>(StaticUtils.computeMapCapacity(10)); 928 929 final String allOpsPropertyValue = StaticUtils.getSystemProperty( 930 PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS); 931 if (allOpsPropertyValue != null) 932 { 933 try 934 { 935 allOpsTimeout = Math.max(0L, Long.parseLong(allOpsPropertyValue)); 936 for (final OperationType ot : OperationType.values()) 937 { 938 timeoutsByOpType.put(ot, allOpsTimeout); 939 } 940 941 if (Debug.debugEnabled()) 942 { 943 Debug.debug(Level.INFO, DebugType.OTHER, 944 "Using value " + allOpsTimeout + " set for system property '" + 945 PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS + "'. This " + 946 "timeout will be used for all operation types."); 947 } 948 } 949 catch (final Exception e) 950 { 951 if (Debug.debugEnabled()) 952 { 953 Debug.debugException(e); 954 Debug.debug(Level.WARNING, DebugType.OTHER, 955 "Invalid value '" + allOpsPropertyValue + "' set for system " + 956 "property '" + PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS + 957 "'. The value was expected to be a long. Ignoring " + 958 "this property and proceeding as if it had not been set."); 959 } 960 } 961 } 962 963 964 // Get the default response timeout for each type of operation. 965 if (allOpsTimeout == null) 966 { 967 allOpsTimeout = 300_000L; 968 969 // Use hard-coded response timeouts of 10 seconds for abandon and unbind 970 // operations. There is no response for these operations, but the timeout 971 // is also used for sending the request. 972 timeoutsByOpType.put(OperationType.ABANDON, 10_000L); 973 timeoutsByOpType.put(OperationType.UNBIND, 10_000L); 974 975 timeoutsByOpType.put(OperationType.ADD, 976 getSystemProperty(PROPERTY_DEFAULT_ADD_RESPONSE_TIMEOUT_MILLIS, 977 30_000L)); 978 timeoutsByOpType.put(OperationType.BIND, 979 getSystemProperty(PROPERTY_DEFAULT_BIND_RESPONSE_TIMEOUT_MILLIS, 980 30_000L)); 981 timeoutsByOpType.put(OperationType.COMPARE, 982 getSystemProperty(PROPERTY_DEFAULT_COMPARE_RESPONSE_TIMEOUT_MILLIS, 983 30_000L)); 984 timeoutsByOpType.put(OperationType.DELETE, 985 getSystemProperty(PROPERTY_DEFAULT_DELETE_RESPONSE_TIMEOUT_MILLIS, 986 30_000L)); 987 timeoutsByOpType.put(OperationType.MODIFY, 988 getSystemProperty(PROPERTY_DEFAULT_MODIFY_RESPONSE_TIMEOUT_MILLIS, 989 30_000L)); 990 timeoutsByOpType.put(OperationType.MODIFY_DN, 991 getSystemProperty(PROPERTY_DEFAULT_MODIFY_DN_RESPONSE_TIMEOUT_MILLIS, 992 30_000L)); 993 timeoutsByOpType.put(OperationType.SEARCH, 994 getSystemProperty(PROPERTY_DEFAULT_SEARCH_RESPONSE_TIMEOUT_MILLIS, 995 300_000L)); 996 997 final String extendedOperationTypePrefix = 998 PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS + '.'; 999 for (final String propertyName : 1000 StaticUtils.getSystemProperties().stringPropertyNames()) 1001 { 1002 if (propertyName.startsWith(extendedOperationTypePrefix)) 1003 { 1004 final Long value = getSystemProperty(propertyName, null); 1005 if (value != null) 1006 { 1007 final String oid = propertyName.substring( 1008 extendedOperationTypePrefix.length()); 1009 timeoutsByExtOpType.put(oid, value); 1010 } 1011 } 1012 } 1013 1014 1015 // Get the default response timeout for different types of extended 1016 // operations. 1017 final Long extendedOpTimeout = getSystemProperty( 1018 PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS, null); 1019 if (extendedOpTimeout == null) 1020 { 1021 timeoutsByOpType.put(OperationType.EXTENDED, 300_000L); 1022 1023 for (final String oid : 1024 Arrays.asList( 1025 PasswordModifyExtendedRequest.PASSWORD_MODIFY_REQUEST_OID, 1026 StartTLSExtendedRequest.STARTTLS_REQUEST_OID, 1027 WhoAmIExtendedRequest.WHO_AM_I_REQUEST_OID, 1028 DeregisterYubiKeyOTPDeviceExtendedRequest. 1029 DEREGISTER_YUBIKEY_OTP_DEVICE_REQUEST_OID, 1030 EndAdministrativeSessionExtendedRequest. 1031 END_ADMIN_SESSION_REQUEST_OID, 1032 GenerateTOTPSharedSecretExtendedRequest. 1033 GENERATE_TOTP_SHARED_SECRET_REQUEST_OID, 1034 GetConnectionIDExtendedRequest.GET_CONNECTION_ID_REQUEST_OID, 1035 GetPasswordQualityRequirementsExtendedRequest. 1036 OID_GET_PASSWORD_QUALITY_REQUIREMENTS_REQUEST, 1037 PasswordPolicyStateExtendedRequest. 1038 PASSWORD_POLICY_STATE_REQUEST_OID, 1039 RegisterYubiKeyOTPDeviceExtendedRequest. 1040 REGISTER_YUBIKEY_OTP_DEVICE_REQUEST_OID, 1041 RevokeTOTPSharedSecretExtendedRequest. 1042 REVOKE_TOTP_SHARED_SECRET_REQUEST_OID, 1043 StartAdministrativeSessionExtendedRequest. 1044 START_ADMIN_SESSION_REQUEST_OID, 1045 ValidateTOTPPasswordExtendedRequest. 1046 VALIDATE_TOTP_PASSWORD_REQUEST_OID)) 1047 { 1048 if (! timeoutsByExtOpType.containsKey(oid)) 1049 { 1050 timeoutsByExtOpType.put(oid, 30_000L); 1051 } 1052 } 1053 } 1054 else 1055 { 1056 timeoutsByOpType.put(OperationType.EXTENDED, extendedOpTimeout); 1057 } 1058 } 1059 1060 1061 // Get the default name resolver to use. If the LDAP SDK is running with 1062 // access to the Ping Identity Directory Server's codebase, then we'll use 1063 // the server's default name resolver instead of the LDAP SDK's. 1064 NameResolver defaultNameResolver = DefaultNameResolver.getInstance(); 1065 try 1066 { 1067 final Class<?> nrClass = Class.forName( 1068 "com.unboundid.directory.server.util.OutageSafeDnsCache"); 1069 final Method getNameResolverMethod = nrClass.getMethod("getNameResolver"); 1070 defaultNameResolver = (NameResolver) getNameResolverMethod.invoke(null); 1071 } 1072 catch (final Exception e) 1073 { 1074 // This is fine. It just means that we're not running with access to the 1075 // server codebase (or a version of the server codebase that supports the 1076 // LDAP SDK's name resolver API). 1077 Debug.debugException(Level.FINEST, e); 1078 } 1079 1080 1081 DEFAULT_RESPONSE_TIMEOUT_MILLIS = allOpsTimeout; 1082 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE = 1083 Collections.unmodifiableMap(timeoutsByOpType); 1084 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE = 1085 Collections.unmodifiableMap(timeoutsByExtOpType); 1086 DEFAULT_NAME_RESOLVER = defaultNameResolver; 1087 } 1088 1089 1090 1091 /** 1092 * The name of a system property that can be used to specify the default value 1093 * for the "allow concurrent socket factory use" behavior. If this property 1094 * is set at the time that this class is loaded, then its value must be 1095 * either "true" or "false". If this property is not set, then a default 1096 * value of "true" will be assumed. 1097 * <BR><BR> 1098 * The full name for this system property is "com.unboundid.ldap.sdk. 1099 * LDAPConnectionOptions.defaultAllowConcurrentSocketFactoryUse". 1100 */ 1101 public static final String 1102 PROPERTY_DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = 1103 PROPERTY_PREFIX + "defaultAllowConcurrentSocketFactoryUse"; 1104 1105 1106 1107 /** 1108 * The default value for the setting that controls the default behavior with 1109 * regard to whether to allow concurrent use of a socket factory to create 1110 * client connections. 1111 */ 1112 private static final boolean DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = 1113 getSystemProperty(PROPERTY_DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE, 1114 true); 1115 1116 1117 1118 /** 1119 * The default {@code SSLSocketVerifier} instance that will be used for 1120 * performing extra validation for {@code SSLSocket} instances. 1121 */ 1122 private static final SSLSocketVerifier DEFAULT_SSL_SOCKET_VERIFIER = 1123 TrustAllSSLSocketVerifier.getInstance(); 1124 1125 1126 1127 // Indicates whether to send an abandon request for any operation for which no 1128 // response is received in the maximum response timeout. 1129 private boolean abandonOnTimeout; 1130 1131 // Indicates whether to use synchronization prevent concurrent use of the 1132 // socket factory instance associated with a connection or set of connections. 1133 private boolean allowConcurrentSocketFactoryUse; 1134 1135 // Indicates whether the connection should attempt to automatically reconnect 1136 // if the connection to the server is lost. 1137 private boolean autoReconnect; 1138 1139 // Indicates whether to allow simple binds that contain a DN but no password. 1140 private boolean bindWithDNRequiresPassword; 1141 1142 // Indicates whether to capture a thread stack trace whenever an attempt is 1143 // made to establish a connection; 1144 private boolean captureConnectStackTrace; 1145 1146 // Indicates whether to attempt to follow any referrals that are encountered. 1147 private boolean followReferrals; 1148 1149 // Indicates whether to use SO_KEEPALIVE for the underlying sockets. 1150 private boolean useKeepAlive; 1151 1152 // Indicates whether to use SO_LINGER for the underlying sockets. 1153 private boolean useLinger; 1154 1155 // Indicates whether to use SO_REUSEADDR for the underlying sockets. 1156 private boolean useReuseAddress; 1157 1158 // Indicates whether all connections in a connection pool should reference 1159 // the same schema. 1160 private boolean usePooledSchema; 1161 1162 // Indicates whether to try to use schema information when reading data from 1163 // the server. 1164 private boolean useSchema; 1165 1166 // Indicates whether to use synchronous mode in which only a single operation 1167 // may be in progress on associated connections at any given time. 1168 private boolean useSynchronousMode; 1169 1170 // Indicates whether to use TCP_NODELAY for the underlying sockets. 1171 private boolean useTCPNoDelay; 1172 1173 // The disconnect handler for associated connections. 1174 private DisconnectHandler disconnectHandler; 1175 1176 // The connect timeout, in milliseconds. 1177 private int connectTimeoutMillis; 1178 1179 // The linger timeout to use if SO_LINGER is to be used. 1180 private int lingerTimeoutSeconds; 1181 1182 // The maximum message size in bytes that will be allowed when reading data 1183 // from a directory server. 1184 private int maxMessageSizeBytes; 1185 1186 // The socket receive buffer size to request. 1187 private int receiveBufferSizeBytes; 1188 1189 // The referral hop limit to use if referral following is enabled. 1190 private int referralHopLimit; 1191 1192 // The socket send buffer size to request. 1193 private int sendBufferSizeBytes; 1194 1195 // The pooled schema timeout, in milliseconds. 1196 private long pooledSchemaTimeoutMillis; 1197 1198 // The response timeout, in milliseconds. 1199 private long responseTimeoutMillis; 1200 1201 private Map<OperationType,Long> responseTimeoutMillisByOperationType; 1202 1203 private Map<String,Long> responseTimeoutMillisByExtendedOperationType; 1204 1205 // The name resolver that will be used to resolve host names to IP addresses. 1206 private NameResolver nameResolver; 1207 1208 // Tne default referral connector that should be used for associated 1209 // connections. 1210 private ReferralConnector referralConnector; 1211 1212 // The SSLSocketVerifier instance to use to perform extra validation on 1213 // newly-established SSLSocket instances. 1214 private SSLSocketVerifier sslSocketVerifier; 1215 1216 // The unsolicited notification handler for associated connections. 1217 private UnsolicitedNotificationHandler unsolicitedNotificationHandler; 1218 1219 1220 1221 /** 1222 * Creates a new set of LDAP connection options with the default settings. 1223 */ 1224 public LDAPConnectionOptions() 1225 { 1226 abandonOnTimeout = DEFAULT_ABANDON_ON_TIMEOUT; 1227 autoReconnect = DEFAULT_AUTO_RECONNECT; 1228 bindWithDNRequiresPassword = DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD; 1229 captureConnectStackTrace = DEFAULT_CAPTURE_CONNECT_STACK_TRACE; 1230 followReferrals = DEFAULT_FOLLOW_REFERRALS; 1231 nameResolver = DEFAULT_NAME_RESOLVER; 1232 useKeepAlive = DEFAULT_USE_KEEPALIVE; 1233 useLinger = DEFAULT_USE_LINGER; 1234 useReuseAddress = DEFAULT_USE_REUSE_ADDRESS; 1235 usePooledSchema = DEFAULT_USE_POOLED_SCHEMA; 1236 useSchema = DEFAULT_USE_SCHEMA; 1237 useSynchronousMode = DEFAULT_USE_SYNCHRONOUS_MODE; 1238 useTCPNoDelay = DEFAULT_USE_TCP_NODELAY; 1239 connectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT_MILLIS; 1240 lingerTimeoutSeconds = DEFAULT_LINGER_TIMEOUT_SECONDS; 1241 maxMessageSizeBytes = DEFAULT_MAX_MESSAGE_SIZE_BYTES; 1242 referralHopLimit = DEFAULT_REFERRAL_HOP_LIMIT; 1243 pooledSchemaTimeoutMillis = DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS; 1244 responseTimeoutMillis = DEFAULT_RESPONSE_TIMEOUT_MILLIS; 1245 receiveBufferSizeBytes = DEFAULT_RECEIVE_BUFFER_SIZE_BYTES; 1246 sendBufferSizeBytes = DEFAULT_SEND_BUFFER_SIZE_BYTES; 1247 disconnectHandler = null; 1248 referralConnector = null; 1249 sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 1250 unsolicitedNotificationHandler = null; 1251 1252 responseTimeoutMillisByOperationType = 1253 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE; 1254 responseTimeoutMillisByExtendedOperationType = 1255 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE; 1256 allowConcurrentSocketFactoryUse = 1257 DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE; 1258 } 1259 1260 1261 1262 /** 1263 * Returns a duplicate of this LDAP connection options object that may be 1264 * modified without impacting this instance. 1265 * 1266 * @return A duplicate of this LDAP connection options object that may be 1267 * modified without impacting this instance. 1268 */ 1269 public LDAPConnectionOptions duplicate() 1270 { 1271 final LDAPConnectionOptions o = new LDAPConnectionOptions(); 1272 1273 o.abandonOnTimeout = abandonOnTimeout; 1274 o.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 1275 o.autoReconnect = autoReconnect; 1276 o.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1277 o.captureConnectStackTrace = captureConnectStackTrace; 1278 o.followReferrals = followReferrals; 1279 o.nameResolver = nameResolver; 1280 o.useKeepAlive = useKeepAlive; 1281 o.useLinger = useLinger; 1282 o.useReuseAddress = useReuseAddress; 1283 o.usePooledSchema = usePooledSchema; 1284 o.useSchema = useSchema; 1285 o.useSynchronousMode = useSynchronousMode; 1286 o.useTCPNoDelay = useTCPNoDelay; 1287 o.connectTimeoutMillis = connectTimeoutMillis; 1288 o.lingerTimeoutSeconds = lingerTimeoutSeconds; 1289 o.maxMessageSizeBytes = maxMessageSizeBytes; 1290 o.pooledSchemaTimeoutMillis = pooledSchemaTimeoutMillis; 1291 o.responseTimeoutMillis = responseTimeoutMillis; 1292 o.referralConnector = referralConnector; 1293 o.referralHopLimit = referralHopLimit; 1294 o.disconnectHandler = disconnectHandler; 1295 o.unsolicitedNotificationHandler = unsolicitedNotificationHandler; 1296 o.receiveBufferSizeBytes = receiveBufferSizeBytes; 1297 o.sendBufferSizeBytes = sendBufferSizeBytes; 1298 o.sslSocketVerifier = sslSocketVerifier; 1299 1300 o.responseTimeoutMillisByOperationType = 1301 responseTimeoutMillisByOperationType; 1302 o.responseTimeoutMillisByExtendedOperationType = 1303 responseTimeoutMillisByExtendedOperationType; 1304 1305 return o; 1306 } 1307 1308 1309 1310 /** 1311 * Indicates whether associated connections should attempt to automatically 1312 * reconnect to the target server if the connection is lost. Note that this 1313 * option will not have any effect on pooled connections because defunct 1314 * pooled connections will be replaced by newly-created connections rather 1315 * than attempting to re-establish the existing connection. 1316 * <BR><BR> 1317 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1318 * inherently fragile and can only work under very limited circumstances. It 1319 * is strongly recommended that a connection pool be used instead of the 1320 * auto-reconnect option, even in cases where only a single connection is 1321 * desired. 1322 * 1323 * @return {@code true} if associated connections should attempt to 1324 * automatically reconnect to the target server if the connection is 1325 * lost, or {@code false} if not. 1326 * 1327 * @deprecated The use of auto-reconnect is strongly discouraged because it 1328 * is inherently fragile and can only work under very limited 1329 * circumstances. It is strongly recommended that a connection 1330 * pool be used instead of the auto-reconnect option, even in 1331 * cases where only a single connection is desired. 1332 */ 1333 @Deprecated() 1334 public boolean autoReconnect() 1335 { 1336 return autoReconnect; 1337 } 1338 1339 1340 1341 /** 1342 * Specifies whether associated connections should attempt to automatically 1343 * reconnect to the target server if the connection is lost. Note that 1344 * automatic reconnection will only be available for authenticated clients if 1345 * the authentication mechanism used provides support for re-binding on a new 1346 * connection. Also note that this option will not have any effect on pooled 1347 * connections because defunct pooled connections will be replaced by 1348 * newly-created connections rather than attempting to re-establish the 1349 * existing connection. Further, auto-reconnect should not be used with 1350 * connections that use StartTLS or some other mechanism to alter the state 1351 * of the connection beyond authentication. 1352 * <BR><BR> 1353 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1354 * inherently fragile and can only work under very limited circumstances. It 1355 * is strongly recommended that a connection pool be used instead of the 1356 * auto-reconnect option, even in cases where only a single connection is 1357 * desired. 1358 * 1359 * @param autoReconnect Specifies whether associated connections should 1360 * attempt to automatically reconnect to the target 1361 * server if the connection is lost. 1362 * 1363 * @deprecated The use of auto-reconnect is strongly discouraged because it 1364 * is inherently fragile and can only work under very limited 1365 * circumstances. It is strongly recommended that a connection 1366 * pool be used instead of the auto-reconnect option, even in 1367 * cases where only a single connection is desired. 1368 */ 1369 @Deprecated() 1370 public void setAutoReconnect(final boolean autoReconnect) 1371 { 1372 this.autoReconnect = autoReconnect; 1373 } 1374 1375 1376 1377 /** 1378 * Retrieves the name resolver that should be used to resolve host names to IP 1379 * addresses. 1380 * 1381 * @return The name resolver that should be used to resolve host names to IP 1382 * addresses. 1383 */ 1384 public NameResolver getNameResolver() 1385 { 1386 return nameResolver; 1387 } 1388 1389 1390 1391 /** 1392 * Sets the name resolver that should be used to resolve host names to IP 1393 * addresses. 1394 * 1395 * @param nameResolver The name resolver that should be used to resolve host 1396 * names to IP addresses. 1397 */ 1398 public void setNameResolver(final NameResolver nameResolver) 1399 { 1400 if (nameResolver == null) 1401 { 1402 this.nameResolver = DEFAULT_NAME_RESOLVER; 1403 } 1404 else 1405 { 1406 this.nameResolver = nameResolver; 1407 } 1408 } 1409 1410 1411 1412 /** 1413 * Indicates whether the SDK should allow simple bind operations that contain 1414 * a bind DN but no password. Binds of this type may represent a security 1415 * vulnerability in client applications because they may cause the client to 1416 * believe that the user is properly authenticated when the server considers 1417 * it to be an unauthenticated connection. 1418 * 1419 * @return {@code true} if the SDK should allow simple bind operations that 1420 * contain a bind DN but no password, or {@code false} if not. 1421 */ 1422 public boolean bindWithDNRequiresPassword() 1423 { 1424 return bindWithDNRequiresPassword; 1425 } 1426 1427 1428 1429 /** 1430 * Specifies whether the SDK should allow simple bind operations that contain 1431 * a bind DN but no password. 1432 * 1433 * @param bindWithDNRequiresPassword Indicates whether the SDK should allow 1434 * simple bind operations that contain a 1435 * bind DN but no password. 1436 */ 1437 public void setBindWithDNRequiresPassword( 1438 final boolean bindWithDNRequiresPassword) 1439 { 1440 this.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1441 } 1442 1443 1444 1445 /** 1446 * Indicates whether the LDAP SDK should capture a thread stack trace for each 1447 * attempt made to establish a connection. If this is enabled, then the 1448 * {@link LDAPConnection#getConnectStackTrace()} method may be used to 1449 * retrieve the stack trace. 1450 * 1451 * @return {@code true} if a thread stack trace should be captured whenever a 1452 * connection is established, or {@code false} if not. 1453 */ 1454 public boolean captureConnectStackTrace() 1455 { 1456 return captureConnectStackTrace; 1457 } 1458 1459 1460 1461 /** 1462 * Specifies whether the LDAP SDK should capture a thread stack trace for each 1463 * attempt made to establish a connection. 1464 * 1465 * @param captureConnectStackTrace Indicates whether to capture a thread 1466 * stack trace for each attempt made to 1467 * establish a connection. 1468 */ 1469 public void setCaptureConnectStackTrace( 1470 final boolean captureConnectStackTrace) 1471 { 1472 this.captureConnectStackTrace = captureConnectStackTrace; 1473 } 1474 1475 1476 1477 /** 1478 * Retrieves the maximum length of time in milliseconds that a connection 1479 * attempt should be allowed to continue before giving up. 1480 * 1481 * @return The maximum length of time in milliseconds that a connection 1482 * attempt should be allowed to continue before giving up, or zero 1483 * to indicate that there should be no connect timeout. 1484 */ 1485 public int getConnectTimeoutMillis() 1486 { 1487 return connectTimeoutMillis; 1488 } 1489 1490 1491 1492 /** 1493 * Specifies the maximum length of time in milliseconds that a connection 1494 * attempt should be allowed to continue before giving up. A value of zero 1495 * indicates that there should be no connect timeout. 1496 * 1497 * @param connectTimeoutMillis The maximum length of time in milliseconds 1498 * that a connection attempt should be allowed 1499 * to continue before giving up. 1500 */ 1501 public void setConnectTimeoutMillis(final int connectTimeoutMillis) 1502 { 1503 this.connectTimeoutMillis = connectTimeoutMillis; 1504 } 1505 1506 1507 1508 /** 1509 * Retrieves the maximum length of time in milliseconds that an operation 1510 * should be allowed to block while waiting for a response from the server. 1511 * This may be overridden on a per-operation type basis, so the 1512 * {@link #getResponseTimeoutMillis(OperationType)} method should be used 1513 * instead of this one. 1514 * 1515 * @return The maximum length of time in milliseconds that an operation 1516 * should be allowed to block while waiting for a response from the 1517 * server, or zero if there should not be any default timeout. 1518 */ 1519 public long getResponseTimeoutMillis() 1520 { 1521 return responseTimeoutMillis; 1522 } 1523 1524 1525 1526 /** 1527 * Specifies the maximum length of time in milliseconds that an operation 1528 * should be allowed to block while waiting for a response from the server. A 1529 * value of zero indicates that there should be no timeout. Note that this 1530 * will override any per-operation type and per-extended operation type 1531 * timeouts that had previously been set. 1532 * 1533 * @param responseTimeoutMillis The maximum length of time in milliseconds 1534 * that an operation should be allowed to block 1535 * while waiting for a response from the 1536 * server. 1537 */ 1538 public void setResponseTimeoutMillis(final long responseTimeoutMillis) 1539 { 1540 this.responseTimeoutMillis = Math.max(0L, responseTimeoutMillis); 1541 responseTimeoutMillisByExtendedOperationType = Collections.emptyMap(); 1542 1543 final EnumMap<OperationType,Long> newOperationTimeouts = 1544 new EnumMap<>(OperationType.class); 1545 for (final OperationType t : OperationType.values()) 1546 { 1547 newOperationTimeouts.put(t, this.responseTimeoutMillis); 1548 } 1549 responseTimeoutMillisByOperationType = 1550 Collections.unmodifiableMap(newOperationTimeouts); 1551 } 1552 1553 1554 1555 /** 1556 * Retrieves the maximum length of time in milliseconds that an operation 1557 * of the specified type should be allowed to block while waiting for a 1558 * response from the server. Note that for extended operations, the response 1559 * timeout may be overridden on a per-request OID basis, so the 1560 * {@link #getExtendedOperationResponseTimeoutMillis(String)} method should be 1561 * used instead of this one for extended operations. 1562 * 1563 * @param operationType The operation type for which to make the 1564 * determination. It must not be {@code null}. 1565 * 1566 * @return The maximum length of time in milliseconds that an operation of 1567 * the specified type should be allowed to block while waiting for a 1568 * response from the server, or zero if there should not be any 1569 * default timeout. 1570 */ 1571 public long getResponseTimeoutMillis(final OperationType operationType) 1572 { 1573 return responseTimeoutMillisByOperationType.get(operationType); 1574 } 1575 1576 1577 1578 /** 1579 * Specifies the maximum length of time in milliseconds that an operation of 1580 * the specified type should be allowed to block while waiting for a response 1581 * from the server. A value of zero indicates that there should be no 1582 * timeout. 1583 * 1584 * @param operationType The operation type for which to set the 1585 * response timeout. It must not be 1586 * {@code null}. 1587 * @param responseTimeoutMillis The maximum length of time in milliseconds 1588 * that an operation should be allowed to block 1589 * while waiting for a response from the 1590 * server. 1591 */ 1592 public void setResponseTimeoutMillis(final OperationType operationType, 1593 final long responseTimeoutMillis) 1594 { 1595 final EnumMap<OperationType,Long> newOperationTimeouts = 1596 new EnumMap<>(OperationType.class); 1597 newOperationTimeouts.putAll(responseTimeoutMillisByOperationType); 1598 newOperationTimeouts.put(operationType, 1599 Math.max(0L, responseTimeoutMillis)); 1600 1601 responseTimeoutMillisByOperationType = Collections.unmodifiableMap( 1602 newOperationTimeouts); 1603 } 1604 1605 1606 1607 /** 1608 * Retrieves the maximum length of time in milliseconds that an extended 1609 * operation with the specified request OID should be allowed to block while 1610 * waiting for a response from the server. 1611 * 1612 * @param requestOID The request OID for the extended operation for which to 1613 * make the determination. It must not be {@code null}. 1614 * 1615 * @return The maximum length of time in milliseconds that the specified type 1616 * of extended operation should be allowed to block while waiting for 1617 * a response from the server, or zero if there should not be any 1618 * default timeout. 1619 */ 1620 public long getExtendedOperationResponseTimeoutMillis(final String requestOID) 1621 { 1622 final Long timeout = 1623 responseTimeoutMillisByExtendedOperationType.get(requestOID); 1624 if (timeout == null) 1625 { 1626 return responseTimeoutMillisByOperationType.get(OperationType.EXTENDED); 1627 } 1628 else 1629 { 1630 return timeout; 1631 } 1632 } 1633 1634 1635 1636 /** 1637 * Specifies the maximum length of time in milliseconds that an extended 1638 * operation with the specified request OID should be allowed to block while 1639 * waiting for a response from the server. A value of zero indicates that 1640 * there should be no timeout. 1641 * 1642 * @param requestOID The request OID for the extended operation 1643 * type for which to set the response timeout. 1644 * It must not be {@code null}. 1645 * @param responseTimeoutMillis The maximum length of time in milliseconds 1646 * that an operation should be allowed to block 1647 * while waiting for a response from the 1648 * server. 1649 */ 1650 public void setExtendedOperationResponseTimeoutMillis(final String requestOID, 1651 final long responseTimeoutMillis) 1652 { 1653 final HashMap<String,Long> newExtOpTimeouts = 1654 new HashMap<>(responseTimeoutMillisByExtendedOperationType); 1655 newExtOpTimeouts.put(requestOID, responseTimeoutMillis); 1656 responseTimeoutMillisByExtendedOperationType = 1657 Collections.unmodifiableMap(newExtOpTimeouts); 1658 } 1659 1660 1661 1662 /** 1663 * Indicates whether the LDAP SDK should attempt to abandon any request for 1664 * which no response is received in the maximum response timeout period. 1665 * 1666 * @return {@code true} if the LDAP SDK should attempt to abandon any request 1667 * for which no response is received in the maximum response timeout 1668 * period, or {@code false} if no abandon attempt should be made in 1669 * this circumstance. 1670 */ 1671 public boolean abandonOnTimeout() 1672 { 1673 return abandonOnTimeout; 1674 } 1675 1676 1677 1678 /** 1679 * Specifies whether the LDAP SDK should attempt to abandon any request for 1680 * which no response is received in the maximum response timeout period. 1681 * 1682 * @param abandonOnTimeout Indicates whether the LDAP SDK should attempt to 1683 * abandon any request for which no response is 1684 * received in the maximum response timeout period. 1685 */ 1686 public void setAbandonOnTimeout(final boolean abandonOnTimeout) 1687 { 1688 this.abandonOnTimeout = abandonOnTimeout; 1689 } 1690 1691 1692 1693 /** 1694 * Indicates whether to use the SO_KEEPALIVE option for the underlying sockets 1695 * used by associated connections. 1696 * 1697 * @return {@code true} if the SO_KEEPALIVE option should be used for the 1698 * underlying sockets, or {@code false} if not. 1699 */ 1700 public boolean useKeepAlive() 1701 { 1702 return useKeepAlive; 1703 } 1704 1705 1706 1707 /** 1708 * Specifies whether to use the SO_KEEPALIVE option for the underlying sockets 1709 * used by associated connections. Changes to this setting will take effect 1710 * only for new sockets, and not for existing sockets. 1711 * 1712 * @param useKeepAlive Indicates whether to use the SO_KEEPALIVE option for 1713 * the underlying sockets used by associated 1714 * connections. 1715 */ 1716 public void setUseKeepAlive(final boolean useKeepAlive) 1717 { 1718 this.useKeepAlive = useKeepAlive; 1719 } 1720 1721 1722 1723 /** 1724 * Indicates whether to use the SO_LINGER option for the underlying sockets 1725 * used by associated connections. 1726 * 1727 * @return {@code true} if the SO_LINGER option should be used for the 1728 * underlying sockets, or {@code false} if not. 1729 */ 1730 public boolean useLinger() 1731 { 1732 return useLinger; 1733 } 1734 1735 1736 1737 /** 1738 * Retrieves the linger timeout in seconds that will be used if the SO_LINGER 1739 * socket option is enabled. 1740 * 1741 * @return The linger timeout in seconds that will be used if the SO_LINGER 1742 * socket option is enabled. 1743 */ 1744 public int getLingerTimeoutSeconds() 1745 { 1746 return lingerTimeoutSeconds; 1747 } 1748 1749 1750 1751 /** 1752 * Specifies whether to use the SO_LINGER option for the underlying sockets 1753 * used by associated connections. Changes to this setting will take effect 1754 * only for new sockets, and not for existing sockets. 1755 * 1756 * @param useLinger Indicates whether to use the SO_LINGER option 1757 * for the underlying sockets used by associated 1758 * connections. 1759 * @param lingerTimeoutSeconds The linger timeout in seconds that should be 1760 * used if this capability is enabled. 1761 */ 1762 public void setUseLinger(final boolean useLinger, 1763 final int lingerTimeoutSeconds) 1764 { 1765 this.useLinger = useLinger; 1766 this.lingerTimeoutSeconds = lingerTimeoutSeconds; 1767 } 1768 1769 1770 1771 /** 1772 * Indicates whether to use the SO_REUSEADDR option for the underlying sockets 1773 * used by associated connections. 1774 * 1775 * @return {@code true} if the SO_REUSEADDR option should be used for the 1776 * underlying sockets, or {@code false} if not. 1777 */ 1778 public boolean useReuseAddress() 1779 { 1780 return useReuseAddress; 1781 } 1782 1783 1784 1785 /** 1786 * Specifies whether to use the SO_REUSEADDR option for the underlying sockets 1787 * used by associated connections. Changes to this setting will take effect 1788 * only for new sockets, and not for existing sockets. 1789 * 1790 * @param useReuseAddress Indicates whether to use the SO_REUSEADDR option 1791 * for the underlying sockets used by associated 1792 * connections. 1793 */ 1794 public void setUseReuseAddress(final boolean useReuseAddress) 1795 { 1796 this.useReuseAddress = useReuseAddress; 1797 } 1798 1799 1800 1801 /** 1802 * Indicates whether to try to use schema information when reading data from 1803 * the server (e.g., to select the appropriate matching rules for the 1804 * attributes included in a search result entry). 1805 * <BR><BR> 1806 * If the LDAP SDK is configured to make use of schema, then it may be able 1807 * to more accurately perform client-side matching, including methods like 1808 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1809 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1810 * then all client-side matching for attribute values will treat them as 1811 * directory string values with a caseIgnoreMatch equality matching rule. If 1812 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1813 * the LDAP SDK may be able to use the attribute type definitions from that 1814 * schema to determine the appropriate syntax and matching rules to use for 1815 * client-side matching operations involving those attributes. Any attribute 1816 * types that are not defined in the schema will still be treated as 1817 * case-insensitive directory string values. 1818 * 1819 * @return {@code true} if schema should be used when reading data from the 1820 * server, or {@code false} if not. 1821 */ 1822 public boolean useSchema() 1823 { 1824 return useSchema; 1825 } 1826 1827 1828 1829 /** 1830 * Specifies whether to try to use schema information when reading data from 1831 * the server (e.g., to select the appropriate matching rules for the 1832 * attributes included in a search result entry). 1833 * <BR><BR> 1834 * If the LDAP SDK is configured to make use of schema, then it may be able 1835 * to more accurately perform client-side matching, including methods like 1836 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1837 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1838 * then all client-side matching for attribute values will treat them as 1839 * directory string values with a caseIgnoreMatch equality matching rule. If 1840 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1841 * the LDAP SDK may be able to use the attribute type definitions from that 1842 * schema to determine the appropriate syntax and matching rules to use for 1843 * client-side matching operations involving those attributes. Any attribute 1844 * types that are not defined in the schema will still be treated as 1845 * case-insensitive directory string values. 1846 * <BR><BR> 1847 * Note that calling this method with a value of {@code true} will also cause 1848 * the {@code usePooledSchema} setting to be given a value of false, since 1849 * the two values should not both be {@code true} at the same time. 1850 * 1851 * @param useSchema Indicates whether to try to use schema information when 1852 * reading data from the server. 1853 */ 1854 public void setUseSchema(final boolean useSchema) 1855 { 1856 this.useSchema = useSchema; 1857 if (useSchema) 1858 { 1859 usePooledSchema = false; 1860 } 1861 } 1862 1863 1864 1865 /** 1866 * Indicates whether to have connections that are part of a pool try to use 1867 * shared schema information when reading data from the server (e.g., to 1868 * select the appropriate matching rules for the attributes included in a 1869 * search result entry). If this is {@code true}, then connections in a 1870 * connection pool will share the same cached schema information in a way that 1871 * attempts to reduce network bandwidth and connection establishment time (by 1872 * avoiding the need for each connection to retrieve its own copy of the 1873 * schema). 1874 * <BR><BR> 1875 * If the LDAP SDK is configured to make use of schema, then it may be able 1876 * to more accurately perform client-side matching, including methods like 1877 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1878 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1879 * then all client-side matching for attribute values will treat them as 1880 * directory string values with a caseIgnoreMatch equality matching rule. If 1881 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1882 * the LDAP SDK may be able to use the attribute type definitions from that 1883 * schema to determine the appropriate syntax and matching rules to use for 1884 * client-side matching operations involving those attributes. Any attribute 1885 * types that are not defined in the schema will still be treated as 1886 * case-insensitive directory string values. 1887 * <BR><BR> 1888 * If pooled schema is to be used, then it may be configured to expire so that 1889 * the schema may be periodically re-retrieved for new connections to allow 1890 * schema updates to be incorporated. This behavior is controlled by the 1891 * value returned by the {@link #getPooledSchemaTimeoutMillis} method. 1892 * 1893 * @return {@code true} if all connections in a connection pool should 1894 * reference the same schema object, or {@code false} if each 1895 * connection should retrieve its own copy of the schema. 1896 */ 1897 public boolean usePooledSchema() 1898 { 1899 return usePooledSchema; 1900 } 1901 1902 1903 1904 /** 1905 * Indicates whether to have connections that are part of a pool try to use 1906 * shared schema information when reading data from the server (e.g., to 1907 * select the appropriate matching rules for the attributes included in a 1908 * search result entry). 1909 * <BR><BR> 1910 * If the LDAP SDK is configured to make use of schema, then it may be able 1911 * to more accurately perform client-side matching, including methods like 1912 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1913 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1914 * then all client-side matching for attribute values will treat them as 1915 * directory string values with a caseIgnoreMatch equality matching rule. If 1916 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1917 * the LDAP SDK may be able to use the attribute type definitions from that 1918 * schema to determine the appropriate syntax and matching rules to use for 1919 * client-side matching operations involving those attributes. Any attribute 1920 * types that are not defined in the schema will still be treated as 1921 * case-insensitive directory string values. 1922 * <BR><BR> 1923 * Note that calling this method with a value of {@code true} will also cause 1924 * the {@code useSchema} setting to be given a value of false, since the two 1925 * values should not both be {@code true} at the same time. 1926 * 1927 * @param usePooledSchema Indicates whether all connections in a connection 1928 * pool should reference the same schema object 1929 * rather than attempting to retrieve their own copy 1930 * of the schema. 1931 */ 1932 public void setUsePooledSchema(final boolean usePooledSchema) 1933 { 1934 this.usePooledSchema = usePooledSchema; 1935 if (usePooledSchema) 1936 { 1937 useSchema = false; 1938 } 1939 } 1940 1941 1942 1943 /** 1944 * Retrieves the maximum length of time in milliseconds that a pooled schema 1945 * object should be considered fresh. If the schema referenced by a 1946 * connection pool is at least this old, then the next connection attempt may 1947 * cause a new version of the schema to be retrieved. 1948 * <BR><BR> 1949 * This will only be used if the {@link #usePooledSchema} method returns 1950 * {@code true}. A value of zero indicates that the pooled schema will never 1951 * expire. 1952 * 1953 * @return The maximum length of time, in milliseconds, that a pooled schema 1954 * object should be considered fresh, or zero if pooled schema 1955 * objects should never expire. 1956 */ 1957 public long getPooledSchemaTimeoutMillis() 1958 { 1959 return pooledSchemaTimeoutMillis; 1960 } 1961 1962 1963 1964 /** 1965 * Specifies the maximum length of time in milliseconds that a pooled schema 1966 * object should be considered fresh. 1967 * 1968 * @param pooledSchemaTimeoutMillis The maximum length of time in 1969 * milliseconds that a pooled schema object 1970 * should be considered fresh. A value 1971 * less than or equal to zero will indicate 1972 * that pooled schema should never expire. 1973 */ 1974 public void setPooledSchemaTimeoutMillis(final long pooledSchemaTimeoutMillis) 1975 { 1976 this.pooledSchemaTimeoutMillis = Math.max(0L, pooledSchemaTimeoutMillis); 1977 } 1978 1979 1980 1981 /** 1982 * Indicates whether to operate in synchronous mode, in which at most one 1983 * operation may be in progress at any time on a given connection, which may 1984 * allow it to operate more efficiently and without requiring a separate 1985 * reader thread per connection. The LDAP SDK will not absolutely enforce 1986 * this restriction, but when operating in this mode correct behavior 1987 * cannot be guaranteed when multiple attempts are made to use a connection 1988 * for multiple concurrent operations. 1989 * <BR><BR> 1990 * Note that if synchronous mode is to be used, then this connection option 1991 * must be set on the connection before any attempt is made to establish the 1992 * connection. Once the connection has been established, then it will 1993 * continue to operate in synchronous or asynchronous mode based on the 1994 * options in place at the time it was connected. 1995 * 1996 * @return {@code true} if associated connections should operate in 1997 * synchronous mode, or {@code false} if not. 1998 */ 1999 public boolean useSynchronousMode() 2000 { 2001 return useSynchronousMode; 2002 } 2003 2004 2005 2006 /** 2007 * Specifies whether to operate in synchronous mode, in which at most one 2008 * operation may be in progress at any time on a given connection. 2009 * <BR><BR> 2010 * Note that if synchronous mode is to be used, then this connection option 2011 * must be set on the connection before any attempt is made to establish the 2012 * connection. Once the connection has been established, then it will 2013 * continue to operate in synchronous or asynchronous mode based on the 2014 * options in place at the time it was connected. 2015 * 2016 * @param useSynchronousMode Indicates whether to operate in synchronous 2017 * mode. 2018 */ 2019 public void setUseSynchronousMode(final boolean useSynchronousMode) 2020 { 2021 this.useSynchronousMode = useSynchronousMode; 2022 } 2023 2024 2025 2026 /** 2027 * Indicates whether to use the TCP_NODELAY option for the underlying sockets 2028 * used by associated connections. 2029 * 2030 * @return {@code true} if the TCP_NODELAY option should be used for the 2031 * underlying sockets, or {@code false} if not. 2032 */ 2033 public boolean useTCPNoDelay() 2034 { 2035 return useTCPNoDelay; 2036 } 2037 2038 2039 2040 /** 2041 * Specifies whether to use the TCP_NODELAY option for the underlying sockets 2042 * used by associated connections. Changes to this setting will take effect 2043 * only for new sockets, and not for existing sockets. 2044 * 2045 * @param useTCPNoDelay Indicates whether to use the TCP_NODELAY option for 2046 * the underlying sockets used by associated 2047 * connections. 2048 */ 2049 public void setUseTCPNoDelay(final boolean useTCPNoDelay) 2050 { 2051 this.useTCPNoDelay = useTCPNoDelay; 2052 } 2053 2054 2055 2056 /** 2057 * Indicates whether associated connections should attempt to follow any 2058 * referrals that they encounter. 2059 * 2060 * @return {@code true} if associated connections should attempt to follow 2061 * any referrals that they encounter, or {@code false} if not. 2062 */ 2063 public boolean followReferrals() 2064 { 2065 return followReferrals; 2066 } 2067 2068 2069 2070 /** 2071 * Specifies whether associated connections should attempt to follow any 2072 * referrals that they encounter, using the referral connector for the 2073 * associated connection. 2074 * 2075 * @param followReferrals Specifies whether associated connections should 2076 * attempt to follow any referrals that they 2077 * encounter. 2078 */ 2079 public void setFollowReferrals(final boolean followReferrals) 2080 { 2081 this.followReferrals = followReferrals; 2082 } 2083 2084 2085 2086 /** 2087 * Retrieves the maximum number of hops that a connection should take when 2088 * trying to follow a referral. 2089 * 2090 * @return The maximum number of hops that a connection should take when 2091 * trying to follow a referral. 2092 */ 2093 public int getReferralHopLimit() 2094 { 2095 return referralHopLimit; 2096 } 2097 2098 2099 2100 /** 2101 * Specifies the maximum number of hops that a connection should take when 2102 * trying to follow a referral. 2103 * 2104 * @param referralHopLimit The maximum number of hops that a connection 2105 * should take when trying to follow a referral. It 2106 * must be greater than zero. 2107 */ 2108 public void setReferralHopLimit(final int referralHopLimit) 2109 { 2110 Validator.ensureTrue(referralHopLimit > 0, 2111 "LDAPConnectionOptions.referralHopLimit must be greater than 0."); 2112 2113 this.referralHopLimit = referralHopLimit; 2114 } 2115 2116 2117 2118 /** 2119 * Retrieves the referral connector that will be used to establish and 2120 * optionally authenticate connections to servers when attempting to follow 2121 * referrals, if defined. 2122 * 2123 * @return The referral connector that will be used to establish and 2124 * optionally authenticate connections to servers when attempting to 2125 * follow referrals, or {@code null} if no specific referral 2126 * connector has been configured and referral connections should be 2127 * created using the same socket factory and bind request as the 2128 * connection on which the referral was received. 2129 */ 2130 public ReferralConnector getReferralConnector() 2131 { 2132 return referralConnector; 2133 } 2134 2135 2136 2137 /** 2138 * Specifies the referral connector that should be used to establish and 2139 * optionally authenticate connections to servers when attempting to follow 2140 * referrals. 2141 * 2142 * @param referralConnector The referral connector that will be used to 2143 * establish and optionally authenticate 2144 * connections to servers when attempting to follow 2145 * referrals. It may be {@code null} to indicate 2146 * that the same socket factory and bind request 2147 * as the connection on which the referral was 2148 * received should be used to establish and 2149 * authenticate connections for following 2150 * referrals. 2151 */ 2152 public void setReferralConnector(final ReferralConnector referralConnector) 2153 { 2154 this.referralConnector = referralConnector; 2155 } 2156 2157 2158 2159 /** 2160 * Retrieves the maximum size in bytes for an LDAP message that a connection 2161 * will attempt to read from the directory server. If it encounters an LDAP 2162 * message that is larger than this size, then the connection will be 2163 * terminated. 2164 * 2165 * @return The maximum size in bytes for an LDAP message that a connection 2166 * will attempt to read from the directory server, or 0 if no limit 2167 * will be enforced. 2168 */ 2169 public int getMaxMessageSize() 2170 { 2171 return maxMessageSizeBytes; 2172 } 2173 2174 2175 2176 /** 2177 * Specifies the maximum size in bytes for an LDAP message that a connection 2178 * will attempt to read from the directory server. If it encounters an LDAP 2179 * message that is larger than this size, then the connection will be 2180 * terminated. 2181 * 2182 * @param maxMessageSizeBytes The maximum size in bytes for an LDAP message 2183 * that a connection will attempt to read from 2184 * the directory server. A value less than or 2185 * equal to zero indicates that no limit should 2186 * be enforced. 2187 */ 2188 public void setMaxMessageSize(final int maxMessageSizeBytes) 2189 { 2190 this.maxMessageSizeBytes = Math.max(0, maxMessageSizeBytes); 2191 } 2192 2193 2194 2195 /** 2196 * Retrieves the disconnect handler to use for associated connections. 2197 * 2198 * @return the disconnect handler to use for associated connections, or 2199 * {@code null} if none is defined. 2200 */ 2201 public DisconnectHandler getDisconnectHandler() 2202 { 2203 return disconnectHandler; 2204 } 2205 2206 2207 2208 /** 2209 * Specifies the disconnect handler to use for associated connections. 2210 * 2211 * @param handler The disconnect handler to use for associated connections. 2212 */ 2213 public void setDisconnectHandler(final DisconnectHandler handler) 2214 { 2215 disconnectHandler = handler; 2216 } 2217 2218 2219 2220 /** 2221 * Retrieves the unsolicited notification handler to use for associated 2222 * connections. 2223 * 2224 * @return The unsolicited notification handler to use for associated 2225 * connections, or {@code null} if none is defined. 2226 */ 2227 public UnsolicitedNotificationHandler getUnsolicitedNotificationHandler() 2228 { 2229 return unsolicitedNotificationHandler; 2230 } 2231 2232 2233 2234 /** 2235 * Specifies the unsolicited notification handler to use for associated 2236 * connections. 2237 * 2238 * @param handler The unsolicited notification handler to use for associated 2239 * connections. 2240 */ 2241 public void setUnsolicitedNotificationHandler( 2242 final UnsolicitedNotificationHandler handler) 2243 { 2244 unsolicitedNotificationHandler = handler; 2245 } 2246 2247 2248 2249 /** 2250 * Retrieves the socket receive buffer size, in bytes, that should be 2251 * requested when establishing a connection. 2252 * 2253 * @return The socket receive buffer size, in bytes, that should be requested 2254 * when establishing a connection, or zero if the JVM's default size 2255 * should be used. 2256 */ 2257 public int getReceiveBufferSize() 2258 { 2259 return receiveBufferSizeBytes; 2260 } 2261 2262 2263 2264 /** 2265 * Specifies the socket receive buffer size, in bytes, that should be 2266 * requested when establishing a connection. 2267 * 2268 * @param receiveBufferSizeBytes The socket receive buffer size, in bytes, 2269 * that should be requested when establishing 2270 * a connection, or zero if the JVM's default 2271 * size should be used. 2272 */ 2273 public void setReceiveBufferSize(final int receiveBufferSizeBytes) 2274 { 2275 this.receiveBufferSizeBytes = Math.max(0, receiveBufferSizeBytes); 2276 } 2277 2278 2279 2280 /** 2281 * Retrieves the socket send buffer size, in bytes, that should be requested 2282 * when establishing a connection. 2283 * 2284 * @return The socket send buffer size, in bytes, that should be requested 2285 * when establishing a connection, or zero if the JVM's default size 2286 * should be used. 2287 */ 2288 public int getSendBufferSize() 2289 { 2290 return sendBufferSizeBytes; 2291 } 2292 2293 2294 2295 /** 2296 * Specifies the socket send buffer size, in bytes, that should be requested 2297 * when establishing a connection. 2298 * 2299 * @param sendBufferSizeBytes The socket send buffer size, in bytes, that 2300 * should be requested when establishing a 2301 * connection, or zero if the JVM's default size 2302 * should be used. 2303 */ 2304 public void setSendBufferSize(final int sendBufferSizeBytes) 2305 { 2306 this.sendBufferSizeBytes = Math.max(0, sendBufferSizeBytes); 2307 } 2308 2309 2310 2311 /** 2312 * Indicates whether to allow a socket factory instance (which may be shared 2313 * across multiple connections) to be used create multiple sockets 2314 * concurrently. In general, socket factory implementations are threadsafe 2315 * and can be to create multiple connections simultaneously across separate 2316 * threads, but this is known to not be the case in some VM implementations 2317 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2318 * indicate whether concurrent socket creation attempts should be allowed 2319 * (which may allow for better and more consistent performance, especially in 2320 * cases where a connection attempt fails due to a timeout) or prevented 2321 * (which may be necessary for non-threadsafe socket factory implementations). 2322 * 2323 * @return {@code true} if multiple threads should be able to concurrently 2324 * use the same socket factory instance, or {@code false} if Java 2325 * synchronization should be used to ensure that no more than one 2326 * thread is allowed to use a socket factory at any given time. 2327 */ 2328 public boolean allowConcurrentSocketFactoryUse() 2329 { 2330 return allowConcurrentSocketFactoryUse; 2331 } 2332 2333 2334 2335 /** 2336 * Specifies whether to allow a socket factory instance (which may be shared 2337 * across multiple connections) to be used create multiple sockets 2338 * concurrently. In general, socket factory implementations are threadsafe 2339 * and can be to create multiple connections simultaneously across separate 2340 * threads, but this is known to not be the case in some VM implementations 2341 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2342 * indicate whether concurrent socket creation attempts should be allowed 2343 * (which may allow for better and more consistent performance, especially in 2344 * cases where a connection attempt fails due to a timeout) or prevented 2345 * (which may be necessary for non-threadsafe socket factory implementations). 2346 * 2347 * @param allowConcurrentSocketFactoryUse Indicates whether to allow a 2348 * socket factory instance to be used 2349 * to create multiple sockets 2350 * concurrently. 2351 */ 2352 public void setAllowConcurrentSocketFactoryUse( 2353 final boolean allowConcurrentSocketFactoryUse) 2354 { 2355 this.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 2356 } 2357 2358 2359 2360 /** 2361 * Retrieves the {@link SSLSocketVerifier} that will be used to perform 2362 * additional validation for any newly-created {@code SSLSocket} instances. 2363 * 2364 * @return The {@code SSLSocketVerifier} that will be used to perform 2365 * additional validation for any newly-created {@code SSLSocket} 2366 * instances. 2367 */ 2368 public SSLSocketVerifier getSSLSocketVerifier() 2369 { 2370 return sslSocketVerifier; 2371 } 2372 2373 2374 2375 /** 2376 * Specifies the {@link SSLSocketVerifier} that will be used to perform 2377 * additional validation for any newly-created {@code SSLSocket} instances. 2378 * 2379 * @param sslSocketVerifier The {@code SSLSocketVerifier} that will be used 2380 * to perform additional validation for any 2381 * newly-created {@code SSLSocket} instances. 2382 */ 2383 public void setSSLSocketVerifier(final SSLSocketVerifier sslSocketVerifier) 2384 { 2385 if (sslSocketVerifier == null) 2386 { 2387 this.sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 2388 } 2389 else 2390 { 2391 this.sslSocketVerifier = sslSocketVerifier; 2392 } 2393 } 2394 2395 2396 2397 /** 2398 * Retrieves the value of the specified system property as a boolean. 2399 * 2400 * @param propertyName The name of the system property whose value should be 2401 * retrieved. 2402 * @param defaultValue The default value that will be returned if the system 2403 * property is not defined or if its value cannot be 2404 * parsed as a boolean. 2405 * 2406 * @return The value of the specified system property as an boolean, or the 2407 * default value if the system property is not set with a valid 2408 * value. 2409 */ 2410 static boolean getSystemProperty(final String propertyName, 2411 final boolean defaultValue) 2412 { 2413 final String propertyValue = StaticUtils.getSystemProperty(propertyName); 2414 if (propertyValue == null) 2415 { 2416 if (Debug.debugEnabled()) 2417 { 2418 Debug.debug(Level.FINE, DebugType.OTHER, 2419 "Using the default value of " + defaultValue + " for system " + 2420 "property '" + propertyName + "' that is not set."); 2421 } 2422 2423 return defaultValue; 2424 } 2425 2426 if (propertyValue.equalsIgnoreCase("true")) 2427 { 2428 if (Debug.debugEnabled()) 2429 { 2430 Debug.debug(Level.INFO, DebugType.OTHER, 2431 "Using value '" + propertyValue + "' set for system property '" + 2432 propertyName + "'."); 2433 } 2434 2435 return true; 2436 } 2437 else if (propertyValue.equalsIgnoreCase("false")) 2438 { 2439 if (Debug.debugEnabled()) 2440 { 2441 Debug.debug(Level.INFO, DebugType.OTHER, 2442 "Using value '" + propertyValue + "' set for system property '" + 2443 propertyName + "'."); 2444 } 2445 2446 return false; 2447 } 2448 else 2449 { 2450 if (Debug.debugEnabled()) 2451 { 2452 Debug.debug(Level.WARNING, DebugType.OTHER, 2453 "Invalid value '" + propertyValue + "' set for system property '" + 2454 propertyName + "'. The value was expected to be either " + 2455 "'true' or 'false'. The default value of " + defaultValue + 2456 " will be used instead of the configured value."); 2457 } 2458 2459 return defaultValue; 2460 } 2461 } 2462 2463 2464 2465 /** 2466 * Retrieves the value of the specified system property as an integer. 2467 * 2468 * @param propertyName The name of the system property whose value should be 2469 * retrieved. 2470 * @param defaultValue The default value that will be returned if the system 2471 * property is not defined or if its value cannot be 2472 * parsed as an integer. 2473 * 2474 * @return The value of the specified system property as an integer, or the 2475 * default value if the system property is not set with a valid 2476 * value. 2477 */ 2478 static int getSystemProperty(final String propertyName, 2479 final int defaultValue) 2480 { 2481 final String propertyValueString = 2482 StaticUtils.getSystemProperty(propertyName); 2483 if (propertyValueString == null) 2484 { 2485 if (Debug.debugEnabled()) 2486 { 2487 Debug.debug(Level.FINE, DebugType.OTHER, 2488 "Using the default value of " + defaultValue + " for system " + 2489 "property '" + propertyName + "' that is not set."); 2490 } 2491 2492 return defaultValue; 2493 } 2494 2495 try 2496 { 2497 final int propertyValueInt = Integer.parseInt(propertyValueString); 2498 if (Debug.debugEnabled()) 2499 { 2500 Debug.debug(Level.INFO, DebugType.OTHER, 2501 "Using value " + propertyValueInt + " set for system property '" + 2502 propertyName + "'."); 2503 } 2504 2505 return propertyValueInt; 2506 } 2507 catch (final Exception e) 2508 { 2509 if (Debug.debugEnabled()) 2510 { 2511 Debug.debugException(e); 2512 Debug.debug(Level.WARNING, DebugType.OTHER, 2513 "Invalid value '" + propertyValueString + "' set for system " + 2514 "property '" + propertyName + "'. The value was expected " + 2515 "to be an integer. The default value of " + defaultValue + 2516 "will be used instead of the configured value.", 2517 e); 2518 } 2519 2520 return defaultValue; 2521 } 2522 } 2523 2524 2525 2526 /** 2527 * Retrieves the value of the specified system property as a long. 2528 * 2529 * @param propertyName The name of the system property whose value should be 2530 * retrieved. 2531 * @param defaultValue The default value that will be returned if the system 2532 * property is not defined or if its value cannot be 2533 * parsed as a long. 2534 * 2535 * @return The value of the specified system property as a long, or the 2536 * default value if the system property is not set with a valid 2537 * value. 2538 */ 2539 static Long getSystemProperty(final String propertyName, 2540 final Long defaultValue) 2541 { 2542 final String propertyValueString = 2543 StaticUtils.getSystemProperty(propertyName); 2544 if (propertyValueString == null) 2545 { 2546 if (Debug.debugEnabled()) 2547 { 2548 Debug.debug(Level.FINE, DebugType.OTHER, 2549 "Using the default value of " + defaultValue + " for system " + 2550 "property '" + propertyName + "' that is not set."); 2551 } 2552 2553 return defaultValue; 2554 } 2555 2556 try 2557 { 2558 final long propertyValueLong = Long.parseLong(propertyValueString); 2559 if (Debug.debugEnabled()) 2560 { 2561 Debug.debug(Level.INFO, DebugType.OTHER, 2562 "Using value " + propertyValueLong + " set for system property '" + 2563 propertyName + "'."); 2564 } 2565 2566 return propertyValueLong; 2567 } 2568 catch (final Exception e) 2569 { 2570 if (Debug.debugEnabled()) 2571 { 2572 Debug.debugException(e); 2573 Debug.debug(Level.WARNING, DebugType.OTHER, 2574 "Invalid value '" + propertyValueString + "' set for system " + 2575 "property '" + propertyName + "'. The value was expected " + 2576 "to be a long. The default value of " + defaultValue + 2577 "will be used instead of the configured value.", 2578 e); 2579 } 2580 2581 return defaultValue; 2582 } 2583 } 2584 2585 2586 2587 /** 2588 * Retrieves a string representation of this LDAP connection. 2589 * 2590 * @return A string representation of this LDAP connection. 2591 */ 2592 @Override() 2593 public String toString() 2594 { 2595 final StringBuilder buffer = new StringBuilder(); 2596 toString(buffer); 2597 return buffer.toString(); 2598 } 2599 2600 2601 2602 /** 2603 * Appends a string representation of this LDAP connection to the provided 2604 * buffer. 2605 * 2606 * @param buffer The buffer to which to append a string representation of 2607 * this LDAP connection. 2608 */ 2609 public void toString(final StringBuilder buffer) 2610 { 2611 buffer.append("LDAPConnectionOptions(autoReconnect="); 2612 buffer.append(autoReconnect); 2613 buffer.append(", nameResolver="); 2614 nameResolver.toString(buffer); 2615 buffer.append(", bindWithDNRequiresPassword="); 2616 buffer.append(bindWithDNRequiresPassword); 2617 buffer.append(", followReferrals="); 2618 buffer.append(followReferrals); 2619 if (followReferrals) 2620 { 2621 buffer.append(", referralHopLimit="); 2622 buffer.append(referralHopLimit); 2623 } 2624 if (referralConnector != null) 2625 { 2626 buffer.append(", referralConnectorClass="); 2627 buffer.append(referralConnector.getClass().getName()); 2628 } 2629 buffer.append(", useKeepAlive="); 2630 buffer.append(useKeepAlive); 2631 buffer.append(", useLinger="); 2632 if (useLinger) 2633 { 2634 buffer.append("true, lingerTimeoutSeconds="); 2635 buffer.append(lingerTimeoutSeconds); 2636 } 2637 else 2638 { 2639 buffer.append("false"); 2640 } 2641 buffer.append(", useReuseAddress="); 2642 buffer.append(useReuseAddress); 2643 buffer.append(", useSchema="); 2644 buffer.append(useSchema); 2645 buffer.append(", usePooledSchema="); 2646 buffer.append(usePooledSchema); 2647 buffer.append(", pooledSchemaTimeoutMillis="); 2648 buffer.append(pooledSchemaTimeoutMillis); 2649 buffer.append(", useSynchronousMode="); 2650 buffer.append(useSynchronousMode); 2651 buffer.append(", useTCPNoDelay="); 2652 buffer.append(useTCPNoDelay); 2653 buffer.append(", captureConnectStackTrace="); 2654 buffer.append(captureConnectStackTrace); 2655 buffer.append(", connectTimeoutMillis="); 2656 buffer.append(connectTimeoutMillis); 2657 buffer.append(", responseTimeoutMillis="); 2658 buffer.append(responseTimeoutMillis); 2659 2660 for (final Map.Entry<OperationType,Long> e : 2661 responseTimeoutMillisByOperationType.entrySet()) 2662 { 2663 buffer.append(", responseTimeoutMillis."); 2664 buffer.append(e.getKey().name()); 2665 buffer.append('='); 2666 buffer.append(e.getValue()); 2667 } 2668 2669 for (final Map.Entry<String,Long> e : 2670 responseTimeoutMillisByExtendedOperationType.entrySet()) 2671 { 2672 buffer.append(", responseTimeoutMillis.EXTENDED."); 2673 buffer.append(e.getKey()); 2674 buffer.append('='); 2675 buffer.append(e.getValue()); 2676 } 2677 2678 buffer.append(", abandonOnTimeout="); 2679 buffer.append(abandonOnTimeout); 2680 buffer.append(", maxMessageSizeBytes="); 2681 buffer.append(maxMessageSizeBytes); 2682 buffer.append(", receiveBufferSizeBytes="); 2683 buffer.append(receiveBufferSizeBytes); 2684 buffer.append(", sendBufferSizeBytes="); 2685 buffer.append(sendBufferSizeBytes); 2686 buffer.append(", allowConcurrentSocketFactoryUse="); 2687 buffer.append(allowConcurrentSocketFactoryUse); 2688 if (disconnectHandler != null) 2689 { 2690 buffer.append(", disconnectHandlerClass="); 2691 buffer.append(disconnectHandler.getClass().getName()); 2692 } 2693 if (unsolicitedNotificationHandler != null) 2694 { 2695 buffer.append(", unsolicitedNotificationHandlerClass="); 2696 buffer.append(unsolicitedNotificationHandler.getClass().getName()); 2697 } 2698 2699 buffer.append(", sslSocketVerifierClass='"); 2700 buffer.append(sslSocketVerifier.getClass().getName()); 2701 buffer.append('\''); 2702 2703 buffer.append(')'); 2704 } 2705}