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 = 930 System.getProperty(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 default value for the setting that controls the default behavior with 1093 * regard to whether to allow concurrent use of a socket factory to create 1094 * client connections. 1095 */ 1096 private static final boolean DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE; 1097 static 1098 { 1099 final String vmVendor = 1100 StaticUtils.toLowerCase(System.getProperty("java.vm.vendor")); 1101 DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = ((vmVendor != null) && 1102 (vmVendor.contains("sun microsystems") || 1103 vmVendor.contains("oracle") || 1104 vmVendor.contains("apple") || 1105 vmVendor.contains("azul systems"))); 1106 } 1107 1108 1109 1110 /** 1111 * The default {@code SSLSocketVerifier} instance that will be used for 1112 * performing extra validation for {@code SSLSocket} instances. 1113 */ 1114 private static final SSLSocketVerifier DEFAULT_SSL_SOCKET_VERIFIER = 1115 TrustAllSSLSocketVerifier.getInstance(); 1116 1117 1118 1119 // Indicates whether to send an abandon request for any operation for which no 1120 // response is received in the maximum response timeout. 1121 private boolean abandonOnTimeout; 1122 1123 // Indicates whether to use synchronization prevent concurrent use of the 1124 // socket factory instance associated with a connection or set of connections. 1125 private boolean allowConcurrentSocketFactoryUse; 1126 1127 // Indicates whether the connection should attempt to automatically reconnect 1128 // if the connection to the server is lost. 1129 private boolean autoReconnect; 1130 1131 // Indicates whether to allow simple binds that contain a DN but no password. 1132 private boolean bindWithDNRequiresPassword; 1133 1134 // Indicates whether to capture a thread stack trace whenever an attempt is 1135 // made to establish a connection; 1136 private boolean captureConnectStackTrace; 1137 1138 // Indicates whether to attempt to follow any referrals that are encountered. 1139 private boolean followReferrals; 1140 1141 // Indicates whether to use SO_KEEPALIVE for the underlying sockets. 1142 private boolean useKeepAlive; 1143 1144 // Indicates whether to use SO_LINGER for the underlying sockets. 1145 private boolean useLinger; 1146 1147 // Indicates whether to use SO_REUSEADDR for the underlying sockets. 1148 private boolean useReuseAddress; 1149 1150 // Indicates whether all connections in a connection pool should reference 1151 // the same schema. 1152 private boolean usePooledSchema; 1153 1154 // Indicates whether to try to use schema information when reading data from 1155 // the server. 1156 private boolean useSchema; 1157 1158 // Indicates whether to use synchronous mode in which only a single operation 1159 // may be in progress on associated connections at any given time. 1160 private boolean useSynchronousMode; 1161 1162 // Indicates whether to use TCP_NODELAY for the underlying sockets. 1163 private boolean useTCPNoDelay; 1164 1165 // The disconnect handler for associated connections. 1166 private DisconnectHandler disconnectHandler; 1167 1168 // The connect timeout, in milliseconds. 1169 private int connectTimeoutMillis; 1170 1171 // The linger timeout to use if SO_LINGER is to be used. 1172 private int lingerTimeoutSeconds; 1173 1174 // The maximum message size in bytes that will be allowed when reading data 1175 // from a directory server. 1176 private int maxMessageSizeBytes; 1177 1178 // The socket receive buffer size to request. 1179 private int receiveBufferSizeBytes; 1180 1181 // The referral hop limit to use if referral following is enabled. 1182 private int referralHopLimit; 1183 1184 // The socket send buffer size to request. 1185 private int sendBufferSizeBytes; 1186 1187 // The pooled schema timeout, in milliseconds. 1188 private long pooledSchemaTimeoutMillis; 1189 1190 // The response timeout, in milliseconds. 1191 private long responseTimeoutMillis; 1192 1193 private Map<OperationType,Long> responseTimeoutMillisByOperationType; 1194 1195 private Map<String,Long> responseTimeoutMillisByExtendedOperationType; 1196 1197 // The name resolver that will be used to resolve host names to IP addresses. 1198 private NameResolver nameResolver; 1199 1200 // Tne default referral connector that should be used for associated 1201 // connections. 1202 private ReferralConnector referralConnector; 1203 1204 // The SSLSocketVerifier instance to use to perform extra validation on 1205 // newly-established SSLSocket instances. 1206 private SSLSocketVerifier sslSocketVerifier; 1207 1208 // The unsolicited notification handler for associated connections. 1209 private UnsolicitedNotificationHandler unsolicitedNotificationHandler; 1210 1211 1212 1213 /** 1214 * Creates a new set of LDAP connection options with the default settings. 1215 */ 1216 public LDAPConnectionOptions() 1217 { 1218 abandonOnTimeout = DEFAULT_ABANDON_ON_TIMEOUT; 1219 autoReconnect = DEFAULT_AUTO_RECONNECT; 1220 bindWithDNRequiresPassword = DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD; 1221 captureConnectStackTrace = DEFAULT_CAPTURE_CONNECT_STACK_TRACE; 1222 followReferrals = DEFAULT_FOLLOW_REFERRALS; 1223 nameResolver = DEFAULT_NAME_RESOLVER; 1224 useKeepAlive = DEFAULT_USE_KEEPALIVE; 1225 useLinger = DEFAULT_USE_LINGER; 1226 useReuseAddress = DEFAULT_USE_REUSE_ADDRESS; 1227 usePooledSchema = DEFAULT_USE_POOLED_SCHEMA; 1228 useSchema = DEFAULT_USE_SCHEMA; 1229 useSynchronousMode = DEFAULT_USE_SYNCHRONOUS_MODE; 1230 useTCPNoDelay = DEFAULT_USE_TCP_NODELAY; 1231 connectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT_MILLIS; 1232 lingerTimeoutSeconds = DEFAULT_LINGER_TIMEOUT_SECONDS; 1233 maxMessageSizeBytes = DEFAULT_MAX_MESSAGE_SIZE_BYTES; 1234 referralHopLimit = DEFAULT_REFERRAL_HOP_LIMIT; 1235 pooledSchemaTimeoutMillis = DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS; 1236 responseTimeoutMillis = DEFAULT_RESPONSE_TIMEOUT_MILLIS; 1237 receiveBufferSizeBytes = DEFAULT_RECEIVE_BUFFER_SIZE_BYTES; 1238 sendBufferSizeBytes = DEFAULT_SEND_BUFFER_SIZE_BYTES; 1239 disconnectHandler = null; 1240 referralConnector = null; 1241 sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 1242 unsolicitedNotificationHandler = null; 1243 1244 responseTimeoutMillisByOperationType = 1245 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE; 1246 responseTimeoutMillisByExtendedOperationType = 1247 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE; 1248 allowConcurrentSocketFactoryUse = 1249 DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE; 1250 } 1251 1252 1253 1254 /** 1255 * Returns a duplicate of this LDAP connection options object that may be 1256 * modified without impacting this instance. 1257 * 1258 * @return A duplicate of this LDAP connection options object that may be 1259 * modified without impacting this instance. 1260 */ 1261 public LDAPConnectionOptions duplicate() 1262 { 1263 final LDAPConnectionOptions o = new LDAPConnectionOptions(); 1264 1265 o.abandonOnTimeout = abandonOnTimeout; 1266 o.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 1267 o.autoReconnect = autoReconnect; 1268 o.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1269 o.captureConnectStackTrace = captureConnectStackTrace; 1270 o.followReferrals = followReferrals; 1271 o.nameResolver = nameResolver; 1272 o.useKeepAlive = useKeepAlive; 1273 o.useLinger = useLinger; 1274 o.useReuseAddress = useReuseAddress; 1275 o.usePooledSchema = usePooledSchema; 1276 o.useSchema = useSchema; 1277 o.useSynchronousMode = useSynchronousMode; 1278 o.useTCPNoDelay = useTCPNoDelay; 1279 o.connectTimeoutMillis = connectTimeoutMillis; 1280 o.lingerTimeoutSeconds = lingerTimeoutSeconds; 1281 o.maxMessageSizeBytes = maxMessageSizeBytes; 1282 o.pooledSchemaTimeoutMillis = pooledSchemaTimeoutMillis; 1283 o.responseTimeoutMillis = responseTimeoutMillis; 1284 o.referralConnector = referralConnector; 1285 o.referralHopLimit = referralHopLimit; 1286 o.disconnectHandler = disconnectHandler; 1287 o.unsolicitedNotificationHandler = unsolicitedNotificationHandler; 1288 o.receiveBufferSizeBytes = receiveBufferSizeBytes; 1289 o.sendBufferSizeBytes = sendBufferSizeBytes; 1290 o.sslSocketVerifier = sslSocketVerifier; 1291 1292 o.responseTimeoutMillisByOperationType = 1293 responseTimeoutMillisByOperationType; 1294 o.responseTimeoutMillisByExtendedOperationType = 1295 responseTimeoutMillisByExtendedOperationType; 1296 1297 return o; 1298 } 1299 1300 1301 1302 /** 1303 * Indicates whether associated connections should attempt to automatically 1304 * reconnect to the target server if the connection is lost. Note that this 1305 * option will not have any effect on pooled connections because defunct 1306 * pooled connections will be replaced by newly-created connections rather 1307 * than attempting to re-establish the existing connection. 1308 * <BR><BR> 1309 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1310 * inherently fragile and can only work under very limited circumstances. It 1311 * is strongly recommended that a connection pool be used instead of the 1312 * auto-reconnect option, even in cases where only a single connection is 1313 * desired. 1314 * 1315 * @return {@code true} if associated connections should attempt to 1316 * automatically reconnect to the target server if the connection is 1317 * lost, or {@code false} if not. 1318 * 1319 * @deprecated The use of auto-reconnect is strongly discouraged because it 1320 * is inherently fragile and can only work under very limited 1321 * circumstances. It is strongly recommended that a connection 1322 * pool be used instead of the auto-reconnect option, even in 1323 * cases where only a single connection is desired. 1324 */ 1325 @Deprecated() 1326 public boolean autoReconnect() 1327 { 1328 return autoReconnect; 1329 } 1330 1331 1332 1333 /** 1334 * Specifies whether associated connections should attempt to automatically 1335 * reconnect to the target server if the connection is lost. Note that 1336 * automatic reconnection will only be available for authenticated clients if 1337 * the authentication mechanism used provides support for re-binding on a new 1338 * connection. Also note that this option will not have any effect on pooled 1339 * connections because defunct pooled connections will be replaced by 1340 * newly-created connections rather than attempting to re-establish the 1341 * existing connection. Further, auto-reconnect should not be used with 1342 * connections that use StartTLS or some other mechanism to alter the state 1343 * of the connection beyond authentication. 1344 * <BR><BR> 1345 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1346 * inherently fragile and can only work under very limited circumstances. It 1347 * is strongly recommended that a connection pool be used instead of the 1348 * auto-reconnect option, even in cases where only a single connection is 1349 * desired. 1350 * 1351 * @param autoReconnect Specifies whether associated connections should 1352 * attempt to automatically reconnect to the target 1353 * server if the connection is lost. 1354 * 1355 * @deprecated The use of auto-reconnect is strongly discouraged because it 1356 * is inherently fragile and can only work under very limited 1357 * circumstances. It is strongly recommended that a connection 1358 * pool be used instead of the auto-reconnect option, even in 1359 * cases where only a single connection is desired. 1360 */ 1361 @Deprecated() 1362 public void setAutoReconnect(final boolean autoReconnect) 1363 { 1364 this.autoReconnect = autoReconnect; 1365 } 1366 1367 1368 1369 /** 1370 * Retrieves the name resolver that should be used to resolve host names to IP 1371 * addresses. 1372 * 1373 * @return The name resolver that should be used to resolve host names to IP 1374 * addresses. 1375 */ 1376 public NameResolver getNameResolver() 1377 { 1378 return nameResolver; 1379 } 1380 1381 1382 1383 /** 1384 * Sets the name resolver that should be used to resolve host names to IP 1385 * addresses. 1386 * 1387 * @param nameResolver The name resolver that should be used to resolve host 1388 * names to IP addresses. 1389 */ 1390 public void setNameResolver(final NameResolver nameResolver) 1391 { 1392 if (nameResolver == null) 1393 { 1394 this.nameResolver = DEFAULT_NAME_RESOLVER; 1395 } 1396 else 1397 { 1398 this.nameResolver = nameResolver; 1399 } 1400 } 1401 1402 1403 1404 /** 1405 * Indicates whether the SDK should allow simple bind operations that contain 1406 * a bind DN but no password. Binds of this type may represent a security 1407 * vulnerability in client applications because they may cause the client to 1408 * believe that the user is properly authenticated when the server considers 1409 * it to be an unauthenticated connection. 1410 * 1411 * @return {@code true} if the SDK should allow simple bind operations that 1412 * contain a bind DN but no password, or {@code false} if not. 1413 */ 1414 public boolean bindWithDNRequiresPassword() 1415 { 1416 return bindWithDNRequiresPassword; 1417 } 1418 1419 1420 1421 /** 1422 * Specifies whether the SDK should allow simple bind operations that contain 1423 * a bind DN but no password. 1424 * 1425 * @param bindWithDNRequiresPassword Indicates whether the SDK should allow 1426 * simple bind operations that contain a 1427 * bind DN but no password. 1428 */ 1429 public void setBindWithDNRequiresPassword( 1430 final boolean bindWithDNRequiresPassword) 1431 { 1432 this.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1433 } 1434 1435 1436 1437 /** 1438 * Indicates whether the LDAP SDK should capture a thread stack trace for each 1439 * attempt made to establish a connection. If this is enabled, then the 1440 * {@link LDAPConnection#getConnectStackTrace()} method may be used to 1441 * retrieve the stack trace. 1442 * 1443 * @return {@code true} if a thread stack trace should be captured whenever a 1444 * connection is established, or {@code false} if not. 1445 */ 1446 public boolean captureConnectStackTrace() 1447 { 1448 return captureConnectStackTrace; 1449 } 1450 1451 1452 1453 /** 1454 * Specifies whether the LDAP SDK should capture a thread stack trace for each 1455 * attempt made to establish a connection. 1456 * 1457 * @param captureConnectStackTrace Indicates whether to capture a thread 1458 * stack trace for each attempt made to 1459 * establish a connection. 1460 */ 1461 public void setCaptureConnectStackTrace( 1462 final boolean captureConnectStackTrace) 1463 { 1464 this.captureConnectStackTrace = captureConnectStackTrace; 1465 } 1466 1467 1468 1469 /** 1470 * Retrieves the maximum length of time in milliseconds that a connection 1471 * attempt should be allowed to continue before giving up. 1472 * 1473 * @return The maximum length of time in milliseconds that a connection 1474 * attempt should be allowed to continue before giving up, or zero 1475 * to indicate that there should be no connect timeout. 1476 */ 1477 public int getConnectTimeoutMillis() 1478 { 1479 return connectTimeoutMillis; 1480 } 1481 1482 1483 1484 /** 1485 * Specifies the maximum length of time in milliseconds that a connection 1486 * attempt should be allowed to continue before giving up. A value of zero 1487 * indicates that there should be no connect timeout. 1488 * 1489 * @param connectTimeoutMillis The maximum length of time in milliseconds 1490 * that a connection attempt should be allowed 1491 * to continue before giving up. 1492 */ 1493 public void setConnectTimeoutMillis(final int connectTimeoutMillis) 1494 { 1495 this.connectTimeoutMillis = connectTimeoutMillis; 1496 } 1497 1498 1499 1500 /** 1501 * Retrieves the maximum length of time in milliseconds that an operation 1502 * should be allowed to block while waiting for a response from the server. 1503 * This may be overridden on a per-operation type basis, so the 1504 * {@link #getResponseTimeoutMillis(OperationType)} method should be used 1505 * instead of this one. 1506 * 1507 * @return The maximum length of time in milliseconds that an operation 1508 * should be allowed to block while waiting for a response from the 1509 * server, or zero if there should not be any default timeout. 1510 */ 1511 public long getResponseTimeoutMillis() 1512 { 1513 return responseTimeoutMillis; 1514 } 1515 1516 1517 1518 /** 1519 * Specifies the maximum length of time in milliseconds that an operation 1520 * should be allowed to block while waiting for a response from the server. A 1521 * value of zero indicates that there should be no timeout. Note that this 1522 * will override any per-operation type and per-extended operation type 1523 * timeouts that had previously been set. 1524 * 1525 * @param responseTimeoutMillis The maximum length of time in milliseconds 1526 * that an operation should be allowed to block 1527 * while waiting for a response from the 1528 * server. 1529 */ 1530 public void setResponseTimeoutMillis(final long responseTimeoutMillis) 1531 { 1532 this.responseTimeoutMillis = Math.max(0L, responseTimeoutMillis); 1533 responseTimeoutMillisByExtendedOperationType = Collections.emptyMap(); 1534 1535 final EnumMap<OperationType,Long> newOperationTimeouts = 1536 new EnumMap<>(OperationType.class); 1537 for (final OperationType t : OperationType.values()) 1538 { 1539 newOperationTimeouts.put(t, this.responseTimeoutMillis); 1540 } 1541 responseTimeoutMillisByOperationType = 1542 Collections.unmodifiableMap(newOperationTimeouts); 1543 } 1544 1545 1546 1547 /** 1548 * Retrieves the maximum length of time in milliseconds that an operation 1549 * of the specified type should be allowed to block while waiting for a 1550 * response from the server. Note that for extended operations, the response 1551 * timeout may be overridden on a per-request OID basis, so the 1552 * {@link #getExtendedOperationResponseTimeoutMillis(String)} method should be 1553 * used instead of this one for extended operations. 1554 * 1555 * @param operationType The operation type for which to make the 1556 * determination. It must not be {@code null}. 1557 * 1558 * @return The maximum length of time in milliseconds that an operation of 1559 * the specified type should be allowed to block while waiting for a 1560 * response from the server, or zero if there should not be any 1561 * default timeout. 1562 */ 1563 public long getResponseTimeoutMillis(final OperationType operationType) 1564 { 1565 return responseTimeoutMillisByOperationType.get(operationType); 1566 } 1567 1568 1569 1570 /** 1571 * Specifies the maximum length of time in milliseconds that an operation of 1572 * the specified type should be allowed to block while waiting for a response 1573 * from the server. A value of zero indicates that there should be no 1574 * timeout. 1575 * 1576 * @param operationType The operation type for which to set the 1577 * response timeout. It must not be 1578 * {@code null}. 1579 * @param responseTimeoutMillis The maximum length of time in milliseconds 1580 * that an operation should be allowed to block 1581 * while waiting for a response from the 1582 * server. 1583 */ 1584 public void setResponseTimeoutMillis(final OperationType operationType, 1585 final long responseTimeoutMillis) 1586 { 1587 final EnumMap<OperationType,Long> newOperationTimeouts = 1588 new EnumMap<>(OperationType.class); 1589 newOperationTimeouts.putAll(responseTimeoutMillisByOperationType); 1590 newOperationTimeouts.put(operationType, 1591 Math.max(0L, responseTimeoutMillis)); 1592 1593 responseTimeoutMillisByOperationType = Collections.unmodifiableMap( 1594 newOperationTimeouts); 1595 } 1596 1597 1598 1599 /** 1600 * Retrieves the maximum length of time in milliseconds that an extended 1601 * operation with the specified request OID should be allowed to block while 1602 * waiting for a response from the server. 1603 * 1604 * @param requestOID The request OID for the extended operation for which to 1605 * make the determination. It must not be {@code null}. 1606 * 1607 * @return The maximum length of time in milliseconds that the specified type 1608 * of extended operation should be allowed to block while waiting for 1609 * a response from the server, or zero if there should not be any 1610 * default timeout. 1611 */ 1612 public long getExtendedOperationResponseTimeoutMillis(final String requestOID) 1613 { 1614 final Long timeout = 1615 responseTimeoutMillisByExtendedOperationType.get(requestOID); 1616 if (timeout == null) 1617 { 1618 return responseTimeoutMillisByOperationType.get(OperationType.EXTENDED); 1619 } 1620 else 1621 { 1622 return timeout; 1623 } 1624 } 1625 1626 1627 1628 /** 1629 * Specifies the maximum length of time in milliseconds that an extended 1630 * operation with the specified request OID should be allowed to block while 1631 * waiting for a response from the server. A value of zero indicates that 1632 * there should be no timeout. 1633 * 1634 * @param requestOID The request OID for the extended operation 1635 * type for which to set the response timeout. 1636 * It must not be {@code null}. 1637 * @param responseTimeoutMillis The maximum length of time in milliseconds 1638 * that an operation should be allowed to block 1639 * while waiting for a response from the 1640 * server. 1641 */ 1642 public void setExtendedOperationResponseTimeoutMillis(final String requestOID, 1643 final long responseTimeoutMillis) 1644 { 1645 final HashMap<String,Long> newExtOpTimeouts = 1646 new HashMap<>(responseTimeoutMillisByExtendedOperationType); 1647 newExtOpTimeouts.put(requestOID, responseTimeoutMillis); 1648 responseTimeoutMillisByExtendedOperationType = 1649 Collections.unmodifiableMap(newExtOpTimeouts); 1650 } 1651 1652 1653 1654 /** 1655 * Indicates whether the LDAP SDK should attempt to abandon any request for 1656 * which no response is received in the maximum response timeout period. 1657 * 1658 * @return {@code true} if the LDAP SDK should attempt to abandon any request 1659 * for which no response is received in the maximum response timeout 1660 * period, or {@code false} if no abandon attempt should be made in 1661 * this circumstance. 1662 */ 1663 public boolean abandonOnTimeout() 1664 { 1665 return abandonOnTimeout; 1666 } 1667 1668 1669 1670 /** 1671 * Specifies whether the LDAP SDK should attempt to abandon any request for 1672 * which no response is received in the maximum response timeout period. 1673 * 1674 * @param abandonOnTimeout Indicates whether the LDAP SDK should attempt to 1675 * abandon any request for which no response is 1676 * received in the maximum response timeout period. 1677 */ 1678 public void setAbandonOnTimeout(final boolean abandonOnTimeout) 1679 { 1680 this.abandonOnTimeout = abandonOnTimeout; 1681 } 1682 1683 1684 1685 /** 1686 * Indicates whether to use the SO_KEEPALIVE option for the underlying sockets 1687 * used by associated connections. 1688 * 1689 * @return {@code true} if the SO_KEEPALIVE option should be used for the 1690 * underlying sockets, or {@code false} if not. 1691 */ 1692 public boolean useKeepAlive() 1693 { 1694 return useKeepAlive; 1695 } 1696 1697 1698 1699 /** 1700 * Specifies whether to use the SO_KEEPALIVE option for the underlying sockets 1701 * used by associated connections. Changes to this setting will take effect 1702 * only for new sockets, and not for existing sockets. 1703 * 1704 * @param useKeepAlive Indicates whether to use the SO_KEEPALIVE option for 1705 * the underlying sockets used by associated 1706 * connections. 1707 */ 1708 public void setUseKeepAlive(final boolean useKeepAlive) 1709 { 1710 this.useKeepAlive = useKeepAlive; 1711 } 1712 1713 1714 1715 /** 1716 * Indicates whether to use the SO_LINGER option for the underlying sockets 1717 * used by associated connections. 1718 * 1719 * @return {@code true} if the SO_LINGER option should be used for the 1720 * underlying sockets, or {@code false} if not. 1721 */ 1722 public boolean useLinger() 1723 { 1724 return useLinger; 1725 } 1726 1727 1728 1729 /** 1730 * Retrieves the linger timeout in seconds that will be used if the SO_LINGER 1731 * socket option is enabled. 1732 * 1733 * @return The linger timeout in seconds that will be used if the SO_LINGER 1734 * socket option is enabled. 1735 */ 1736 public int getLingerTimeoutSeconds() 1737 { 1738 return lingerTimeoutSeconds; 1739 } 1740 1741 1742 1743 /** 1744 * Specifies whether to use the SO_LINGER option for the underlying sockets 1745 * used by associated connections. Changes to this setting will take effect 1746 * only for new sockets, and not for existing sockets. 1747 * 1748 * @param useLinger Indicates whether to use the SO_LINGER option 1749 * for the underlying sockets used by associated 1750 * connections. 1751 * @param lingerTimeoutSeconds The linger timeout in seconds that should be 1752 * used if this capability is enabled. 1753 */ 1754 public void setUseLinger(final boolean useLinger, 1755 final int lingerTimeoutSeconds) 1756 { 1757 this.useLinger = useLinger; 1758 this.lingerTimeoutSeconds = lingerTimeoutSeconds; 1759 } 1760 1761 1762 1763 /** 1764 * Indicates whether to use the SO_REUSEADDR option for the underlying sockets 1765 * used by associated connections. 1766 * 1767 * @return {@code true} if the SO_REUSEADDR option should be used for the 1768 * underlying sockets, or {@code false} if not. 1769 */ 1770 public boolean useReuseAddress() 1771 { 1772 return useReuseAddress; 1773 } 1774 1775 1776 1777 /** 1778 * Specifies whether to use the SO_REUSEADDR option for the underlying sockets 1779 * used by associated connections. Changes to this setting will take effect 1780 * only for new sockets, and not for existing sockets. 1781 * 1782 * @param useReuseAddress Indicates whether to use the SO_REUSEADDR option 1783 * for the underlying sockets used by associated 1784 * connections. 1785 */ 1786 public void setUseReuseAddress(final boolean useReuseAddress) 1787 { 1788 this.useReuseAddress = useReuseAddress; 1789 } 1790 1791 1792 1793 /** 1794 * Indicates whether to try to use schema information when reading data from 1795 * the server (e.g., to select the appropriate matching rules for the 1796 * attributes included in a search result entry). 1797 * <BR><BR> 1798 * If the LDAP SDK is configured to make use of schema, then it may be able 1799 * to more accurately perform client-side matching, including methods like 1800 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1801 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1802 * then all client-side matching for attribute values will treat them as 1803 * directory string values with a caseIgnoreMatch equality matching rule. If 1804 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1805 * the LDAP SDK may be able to use the attribute type definitions from that 1806 * schema to determine the appropriate syntax and matching rules to use for 1807 * client-side matching operations involving those attributes. Any attribute 1808 * types that are not defined in the schema will still be treated as 1809 * case-insensitive directory string values. 1810 * 1811 * @return {@code true} if schema should be used when reading data from the 1812 * server, or {@code false} if not. 1813 */ 1814 public boolean useSchema() 1815 { 1816 return useSchema; 1817 } 1818 1819 1820 1821 /** 1822 * Specifies whether to try to use schema information when reading data from 1823 * the server (e.g., to select the appropriate matching rules for the 1824 * attributes included in a search result entry). 1825 * <BR><BR> 1826 * If the LDAP SDK is configured to make use of schema, then it may be able 1827 * to more accurately perform client-side matching, including methods like 1828 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1829 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1830 * then all client-side matching for attribute values will treat them as 1831 * directory string values with a caseIgnoreMatch equality matching rule. If 1832 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1833 * the LDAP SDK may be able to use the attribute type definitions from that 1834 * schema to determine the appropriate syntax and matching rules to use for 1835 * client-side matching operations involving those attributes. Any attribute 1836 * types that are not defined in the schema will still be treated as 1837 * case-insensitive directory string values. 1838 * <BR><BR> 1839 * Note that calling this method with a value of {@code true} will also cause 1840 * the {@code usePooledSchema} setting to be given a value of false, since 1841 * the two values should not both be {@code true} at the same time. 1842 * 1843 * @param useSchema Indicates whether to try to use schema information when 1844 * reading data from the server. 1845 */ 1846 public void setUseSchema(final boolean useSchema) 1847 { 1848 this.useSchema = useSchema; 1849 if (useSchema) 1850 { 1851 usePooledSchema = false; 1852 } 1853 } 1854 1855 1856 1857 /** 1858 * Indicates whether to have connections that are part of a pool try to use 1859 * shared schema information when reading data from the server (e.g., to 1860 * select the appropriate matching rules for the attributes included in a 1861 * search result entry). If this is {@code true}, then connections in a 1862 * connection pool will share the same cached schema information in a way that 1863 * attempts to reduce network bandwidth and connection establishment time (by 1864 * avoiding the need for each connection to retrieve its own copy of the 1865 * schema). 1866 * <BR><BR> 1867 * If the LDAP SDK is configured to make use of schema, then it may be able 1868 * to more accurately perform client-side matching, including methods like 1869 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1870 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1871 * then all client-side matching for attribute values will treat them as 1872 * directory string values with a caseIgnoreMatch equality matching rule. If 1873 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1874 * the LDAP SDK may be able to use the attribute type definitions from that 1875 * schema to determine the appropriate syntax and matching rules to use for 1876 * client-side matching operations involving those attributes. Any attribute 1877 * types that are not defined in the schema will still be treated as 1878 * case-insensitive directory string values. 1879 * <BR><BR> 1880 * If pooled schema is to be used, then it may be configured to expire so that 1881 * the schema may be periodically re-retrieved for new connections to allow 1882 * schema updates to be incorporated. This behavior is controlled by the 1883 * value returned by the {@link #getPooledSchemaTimeoutMillis} method. 1884 * 1885 * @return {@code true} if all connections in a connection pool should 1886 * reference the same schema object, or {@code false} if each 1887 * connection should retrieve its own copy of the schema. 1888 */ 1889 public boolean usePooledSchema() 1890 { 1891 return usePooledSchema; 1892 } 1893 1894 1895 1896 /** 1897 * Indicates whether to have connections that are part of a pool try to use 1898 * shared schema information when reading data from the server (e.g., to 1899 * select the appropriate matching rules for the attributes included in a 1900 * search result entry). 1901 * <BR><BR> 1902 * If the LDAP SDK is configured to make use of schema, then it may be able 1903 * to more accurately perform client-side matching, including methods like 1904 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1905 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1906 * then all client-side matching for attribute values will treat them as 1907 * directory string values with a caseIgnoreMatch equality matching rule. If 1908 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1909 * the LDAP SDK may be able to use the attribute type definitions from that 1910 * schema to determine the appropriate syntax and matching rules to use for 1911 * client-side matching operations involving those attributes. Any attribute 1912 * types that are not defined in the schema will still be treated as 1913 * case-insensitive directory string values. 1914 * <BR><BR> 1915 * Note that calling this method with a value of {@code true} will also cause 1916 * the {@code useSchema} setting to be given a value of false, since the two 1917 * values should not both be {@code true} at the same time. 1918 * 1919 * @param usePooledSchema Indicates whether all connections in a connection 1920 * pool should reference the same schema object 1921 * rather than attempting to retrieve their own copy 1922 * of the schema. 1923 */ 1924 public void setUsePooledSchema(final boolean usePooledSchema) 1925 { 1926 this.usePooledSchema = usePooledSchema; 1927 if (usePooledSchema) 1928 { 1929 useSchema = false; 1930 } 1931 } 1932 1933 1934 1935 /** 1936 * Retrieves the maximum length of time in milliseconds that a pooled schema 1937 * object should be considered fresh. If the schema referenced by a 1938 * connection pool is at least this old, then the next connection attempt may 1939 * cause a new version of the schema to be retrieved. 1940 * <BR><BR> 1941 * This will only be used if the {@link #usePooledSchema} method returns 1942 * {@code true}. A value of zero indicates that the pooled schema will never 1943 * expire. 1944 * 1945 * @return The maximum length of time, in milliseconds, that a pooled schema 1946 * object should be considered fresh, or zero if pooled schema 1947 * objects should never expire. 1948 */ 1949 public long getPooledSchemaTimeoutMillis() 1950 { 1951 return pooledSchemaTimeoutMillis; 1952 } 1953 1954 1955 1956 /** 1957 * Specifies the maximum length of time in milliseconds that a pooled schema 1958 * object should be considered fresh. 1959 * 1960 * @param pooledSchemaTimeoutMillis The maximum length of time in 1961 * milliseconds that a pooled schema object 1962 * should be considered fresh. A value 1963 * less than or equal to zero will indicate 1964 * that pooled schema should never expire. 1965 */ 1966 public void setPooledSchemaTimeoutMillis(final long pooledSchemaTimeoutMillis) 1967 { 1968 this.pooledSchemaTimeoutMillis = Math.max(0L, pooledSchemaTimeoutMillis); 1969 } 1970 1971 1972 1973 /** 1974 * Indicates whether to operate in synchronous mode, in which at most one 1975 * operation may be in progress at any time on a given connection, which may 1976 * allow it to operate more efficiently and without requiring a separate 1977 * reader thread per connection. The LDAP SDK will not absolutely enforce 1978 * this restriction, but when operating in this mode correct behavior 1979 * cannot be guaranteed when multiple attempts are made to use a connection 1980 * for multiple concurrent operations. 1981 * <BR><BR> 1982 * Note that if synchronous mode is to be used, then this connection option 1983 * must be set on the connection before any attempt is made to establish the 1984 * connection. Once the connection has been established, then it will 1985 * continue to operate in synchronous or asynchronous mode based on the 1986 * options in place at the time it was connected. 1987 * 1988 * @return {@code true} if associated connections should operate in 1989 * synchronous mode, or {@code false} if not. 1990 */ 1991 public boolean useSynchronousMode() 1992 { 1993 return useSynchronousMode; 1994 } 1995 1996 1997 1998 /** 1999 * Specifies whether to operate in synchronous mode, in which at most one 2000 * operation may be in progress at any time on a given connection. 2001 * <BR><BR> 2002 * Note that if synchronous mode is to be used, then this connection option 2003 * must be set on the connection before any attempt is made to establish the 2004 * connection. Once the connection has been established, then it will 2005 * continue to operate in synchronous or asynchronous mode based on the 2006 * options in place at the time it was connected. 2007 * 2008 * @param useSynchronousMode Indicates whether to operate in synchronous 2009 * mode. 2010 */ 2011 public void setUseSynchronousMode(final boolean useSynchronousMode) 2012 { 2013 this.useSynchronousMode = useSynchronousMode; 2014 } 2015 2016 2017 2018 /** 2019 * Indicates whether to use the TCP_NODELAY option for the underlying sockets 2020 * used by associated connections. 2021 * 2022 * @return {@code true} if the TCP_NODELAY option should be used for the 2023 * underlying sockets, or {@code false} if not. 2024 */ 2025 public boolean useTCPNoDelay() 2026 { 2027 return useTCPNoDelay; 2028 } 2029 2030 2031 2032 /** 2033 * Specifies whether to use the TCP_NODELAY option for the underlying sockets 2034 * used by associated connections. Changes to this setting will take effect 2035 * only for new sockets, and not for existing sockets. 2036 * 2037 * @param useTCPNoDelay Indicates whether to use the TCP_NODELAY option for 2038 * the underlying sockets used by associated 2039 * connections. 2040 */ 2041 public void setUseTCPNoDelay(final boolean useTCPNoDelay) 2042 { 2043 this.useTCPNoDelay = useTCPNoDelay; 2044 } 2045 2046 2047 2048 /** 2049 * Indicates whether associated connections should attempt to follow any 2050 * referrals that they encounter. 2051 * 2052 * @return {@code true} if associated connections should attempt to follow 2053 * any referrals that they encounter, or {@code false} if not. 2054 */ 2055 public boolean followReferrals() 2056 { 2057 return followReferrals; 2058 } 2059 2060 2061 2062 /** 2063 * Specifies whether associated connections should attempt to follow any 2064 * referrals that they encounter, using the referral connector for the 2065 * associated connection. 2066 * 2067 * @param followReferrals Specifies whether associated connections should 2068 * attempt to follow any referrals that they 2069 * encounter. 2070 */ 2071 public void setFollowReferrals(final boolean followReferrals) 2072 { 2073 this.followReferrals = followReferrals; 2074 } 2075 2076 2077 2078 /** 2079 * Retrieves the maximum number of hops that a connection should take when 2080 * trying to follow a referral. 2081 * 2082 * @return The maximum number of hops that a connection should take when 2083 * trying to follow a referral. 2084 */ 2085 public int getReferralHopLimit() 2086 { 2087 return referralHopLimit; 2088 } 2089 2090 2091 2092 /** 2093 * Specifies the maximum number of hops that a connection should take when 2094 * trying to follow a referral. 2095 * 2096 * @param referralHopLimit The maximum number of hops that a connection 2097 * should take when trying to follow a referral. It 2098 * must be greater than zero. 2099 */ 2100 public void setReferralHopLimit(final int referralHopLimit) 2101 { 2102 Validator.ensureTrue(referralHopLimit > 0, 2103 "LDAPConnectionOptions.referralHopLimit must be greater than 0."); 2104 2105 this.referralHopLimit = referralHopLimit; 2106 } 2107 2108 2109 2110 /** 2111 * Retrieves the referral connector that will be used to establish and 2112 * optionally authenticate connections to servers when attempting to follow 2113 * referrals, if defined. 2114 * 2115 * @return The referral connector that will be used to establish and 2116 * optionally authenticate connections to servers when attempting to 2117 * follow referrals, or {@code null} if no specific referral 2118 * connector has been configured and referral connections should be 2119 * created using the same socket factory and bind request as the 2120 * connection on which the referral was received. 2121 */ 2122 public ReferralConnector getReferralConnector() 2123 { 2124 return referralConnector; 2125 } 2126 2127 2128 2129 /** 2130 * Specifies the referral connector that should be used to establish and 2131 * optionally authenticate connections to servers when attempting to follow 2132 * referrals. 2133 * 2134 * @param referralConnector The referral connector that will be used to 2135 * establish and optionally authenticate 2136 * connections to servers when attempting to follow 2137 * referrals. It may be {@code null} to indicate 2138 * that the same socket factory and bind request 2139 * as the connection on which the referral was 2140 * received should be used to establish and 2141 * authenticate connections for following 2142 * referrals. 2143 */ 2144 public void setReferralConnector(final ReferralConnector referralConnector) 2145 { 2146 this.referralConnector = referralConnector; 2147 } 2148 2149 2150 2151 /** 2152 * Retrieves the maximum size in bytes for an LDAP message that a connection 2153 * will attempt to read from the directory server. If it encounters an LDAP 2154 * message that is larger than this size, then the connection will be 2155 * terminated. 2156 * 2157 * @return The maximum size in bytes for an LDAP message that a connection 2158 * will attempt to read from the directory server, or 0 if no limit 2159 * will be enforced. 2160 */ 2161 public int getMaxMessageSize() 2162 { 2163 return maxMessageSizeBytes; 2164 } 2165 2166 2167 2168 /** 2169 * Specifies the maximum size in bytes for an LDAP message that a connection 2170 * will attempt to read from the directory server. If it encounters an LDAP 2171 * message that is larger than this size, then the connection will be 2172 * terminated. 2173 * 2174 * @param maxMessageSizeBytes The maximum size in bytes for an LDAP message 2175 * that a connection will attempt to read from 2176 * the directory server. A value less than or 2177 * equal to zero indicates that no limit should 2178 * be enforced. 2179 */ 2180 public void setMaxMessageSize(final int maxMessageSizeBytes) 2181 { 2182 this.maxMessageSizeBytes = Math.max(0, maxMessageSizeBytes); 2183 } 2184 2185 2186 2187 /** 2188 * Retrieves the disconnect handler to use for associated connections. 2189 * 2190 * @return the disconnect handler to use for associated connections, or 2191 * {@code null} if none is defined. 2192 */ 2193 public DisconnectHandler getDisconnectHandler() 2194 { 2195 return disconnectHandler; 2196 } 2197 2198 2199 2200 /** 2201 * Specifies the disconnect handler to use for associated connections. 2202 * 2203 * @param handler The disconnect handler to use for associated connections. 2204 */ 2205 public void setDisconnectHandler(final DisconnectHandler handler) 2206 { 2207 disconnectHandler = handler; 2208 } 2209 2210 2211 2212 /** 2213 * Retrieves the unsolicited notification handler to use for associated 2214 * connections. 2215 * 2216 * @return The unsolicited notification handler to use for associated 2217 * connections, or {@code null} if none is defined. 2218 */ 2219 public UnsolicitedNotificationHandler getUnsolicitedNotificationHandler() 2220 { 2221 return unsolicitedNotificationHandler; 2222 } 2223 2224 2225 2226 /** 2227 * Specifies the unsolicited notification handler to use for associated 2228 * connections. 2229 * 2230 * @param handler The unsolicited notification handler to use for associated 2231 * connections. 2232 */ 2233 public void setUnsolicitedNotificationHandler( 2234 final UnsolicitedNotificationHandler handler) 2235 { 2236 unsolicitedNotificationHandler = handler; 2237 } 2238 2239 2240 2241 /** 2242 * Retrieves the socket receive buffer size, in bytes, that should be 2243 * requested when establishing a connection. 2244 * 2245 * @return The socket receive buffer size, in bytes, that should be requested 2246 * when establishing a connection, or zero if the JVM's default size 2247 * should be used. 2248 */ 2249 public int getReceiveBufferSize() 2250 { 2251 return receiveBufferSizeBytes; 2252 } 2253 2254 2255 2256 /** 2257 * Specifies the socket receive buffer size, in bytes, that should be 2258 * requested when establishing a connection. 2259 * 2260 * @param receiveBufferSizeBytes The socket receive buffer size, in bytes, 2261 * that should be requested when establishing 2262 * a connection, or zero if the JVM's default 2263 * size should be used. 2264 */ 2265 public void setReceiveBufferSize(final int receiveBufferSizeBytes) 2266 { 2267 this.receiveBufferSizeBytes = Math.max(0, receiveBufferSizeBytes); 2268 } 2269 2270 2271 2272 /** 2273 * Retrieves the socket send buffer size, in bytes, that should be requested 2274 * when establishing a connection. 2275 * 2276 * @return The socket send buffer size, in bytes, that should be requested 2277 * when establishing a connection, or zero if the JVM's default size 2278 * should be used. 2279 */ 2280 public int getSendBufferSize() 2281 { 2282 return sendBufferSizeBytes; 2283 } 2284 2285 2286 2287 /** 2288 * Specifies the socket send buffer size, in bytes, that should be requested 2289 * when establishing a connection. 2290 * 2291 * @param sendBufferSizeBytes The socket send buffer size, in bytes, that 2292 * should be requested when establishing a 2293 * connection, or zero if the JVM's default size 2294 * should be used. 2295 */ 2296 public void setSendBufferSize(final int sendBufferSizeBytes) 2297 { 2298 this.sendBufferSizeBytes = Math.max(0, sendBufferSizeBytes); 2299 } 2300 2301 2302 2303 /** 2304 * Indicates whether to allow a socket factory instance (which may be shared 2305 * across multiple connections) to be used create multiple sockets 2306 * concurrently. In general, socket factory implementations are threadsafe 2307 * and can be to create multiple connections simultaneously across separate 2308 * threads, but this is known to not be the case in some VM implementations 2309 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2310 * indicate whether concurrent socket creation attempts should be allowed 2311 * (which may allow for better and more consistent performance, especially in 2312 * cases where a connection attempt fails due to a timeout) or prevented 2313 * (which may be necessary for non-threadsafe socket factory implementations). 2314 * 2315 * @return {@code true} if multiple threads should be able to concurrently 2316 * use the same socket factory instance, or {@code false} if Java 2317 * synchronization should be used to ensure that no more than one 2318 * thread is allowed to use a socket factory at any given time. 2319 */ 2320 public boolean allowConcurrentSocketFactoryUse() 2321 { 2322 return allowConcurrentSocketFactoryUse; 2323 } 2324 2325 2326 2327 /** 2328 * Specifies whether to allow a socket factory instance (which may be shared 2329 * across multiple connections) to be used create multiple sockets 2330 * concurrently. In general, socket factory implementations are threadsafe 2331 * and can be to create multiple connections simultaneously across separate 2332 * threads, but this is known to not be the case in some VM implementations 2333 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2334 * indicate whether concurrent socket creation attempts should be allowed 2335 * (which may allow for better and more consistent performance, especially in 2336 * cases where a connection attempt fails due to a timeout) or prevented 2337 * (which may be necessary for non-threadsafe socket factory implementations). 2338 * 2339 * @param allowConcurrentSocketFactoryUse Indicates whether to allow a 2340 * socket factory instance to be used 2341 * to create multiple sockets 2342 * concurrently. 2343 */ 2344 public void setAllowConcurrentSocketFactoryUse( 2345 final boolean allowConcurrentSocketFactoryUse) 2346 { 2347 this.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 2348 } 2349 2350 2351 2352 /** 2353 * Retrieves the {@link SSLSocketVerifier} that will be used to perform 2354 * additional validation for any newly-created {@code SSLSocket} instances. 2355 * 2356 * @return The {@code SSLSocketVerifier} that will be used to perform 2357 * additional validation for any newly-created {@code SSLSocket} 2358 * instances. 2359 */ 2360 public SSLSocketVerifier getSSLSocketVerifier() 2361 { 2362 return sslSocketVerifier; 2363 } 2364 2365 2366 2367 /** 2368 * Specifies the {@link SSLSocketVerifier} that will be used to perform 2369 * additional validation for any newly-created {@code SSLSocket} instances. 2370 * 2371 * @param sslSocketVerifier The {@code SSLSocketVerifier} that will be used 2372 * to perform additional validation for any 2373 * newly-created {@code SSLSocket} instances. 2374 */ 2375 public void setSSLSocketVerifier(final SSLSocketVerifier sslSocketVerifier) 2376 { 2377 if (sslSocketVerifier == null) 2378 { 2379 this.sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 2380 } 2381 else 2382 { 2383 this.sslSocketVerifier = sslSocketVerifier; 2384 } 2385 } 2386 2387 2388 2389 /** 2390 * Retrieves the value of the specified system property as a boolean. 2391 * 2392 * @param propertyName The name of the system property whose value should be 2393 * retrieved. 2394 * @param defaultValue The default value that will be returned if the system 2395 * property is not defined or if its value cannot be 2396 * parsed as a boolean. 2397 * 2398 * @return The value of the specified system property as an boolean, or the 2399 * default value if the system property is not set with a valid 2400 * value. 2401 */ 2402 static boolean getSystemProperty(final String propertyName, 2403 final boolean defaultValue) 2404 { 2405 final String propertyValue = System.getProperty(propertyName); 2406 if (propertyValue == null) 2407 { 2408 if (Debug.debugEnabled()) 2409 { 2410 Debug.debug(Level.FINE, DebugType.OTHER, 2411 "Using the default value of " + defaultValue + " for system " + 2412 "property '" + propertyName + "' that is not set."); 2413 } 2414 2415 return defaultValue; 2416 } 2417 2418 if (propertyValue.equalsIgnoreCase("true")) 2419 { 2420 if (Debug.debugEnabled()) 2421 { 2422 Debug.debug(Level.INFO, DebugType.OTHER, 2423 "Using value '" + propertyValue + "' set for system property '" + 2424 propertyName + "'."); 2425 } 2426 2427 return true; 2428 } 2429 else if (propertyValue.equalsIgnoreCase("false")) 2430 { 2431 if (Debug.debugEnabled()) 2432 { 2433 Debug.debug(Level.INFO, DebugType.OTHER, 2434 "Using value '" + propertyValue + "' set for system property '" + 2435 propertyName + "'."); 2436 } 2437 2438 return false; 2439 } 2440 else 2441 { 2442 if (Debug.debugEnabled()) 2443 { 2444 Debug.debug(Level.WARNING, DebugType.OTHER, 2445 "Invalid value '" + propertyValue + "' set for system property '" + 2446 propertyName + "'. The value was expected to be either " + 2447 "'true' or 'false'. The default value of " + defaultValue + 2448 " will be used instead of the configured value."); 2449 } 2450 2451 return defaultValue; 2452 } 2453 } 2454 2455 2456 2457 /** 2458 * Retrieves the value of the specified system property as an integer. 2459 * 2460 * @param propertyName The name of the system property whose value should be 2461 * retrieved. 2462 * @param defaultValue The default value that will be returned if the system 2463 * property is not defined or if its value cannot be 2464 * parsed as an integer. 2465 * 2466 * @return The value of the specified system property as an integer, or the 2467 * default value if the system property is not set with a valid 2468 * value. 2469 */ 2470 static int getSystemProperty(final String propertyName, 2471 final int defaultValue) 2472 { 2473 final String propertyValueString = System.getProperty(propertyName); 2474 if (propertyValueString == null) 2475 { 2476 if (Debug.debugEnabled()) 2477 { 2478 Debug.debug(Level.FINE, DebugType.OTHER, 2479 "Using the default value of " + defaultValue + " for system " + 2480 "property '" + propertyName + "' that is not set."); 2481 } 2482 2483 return defaultValue; 2484 } 2485 2486 try 2487 { 2488 final int propertyValueInt = Integer.parseInt(propertyValueString); 2489 if (Debug.debugEnabled()) 2490 { 2491 Debug.debug(Level.INFO, DebugType.OTHER, 2492 "Using value " + propertyValueInt + " set for system property '" + 2493 propertyName + "'."); 2494 } 2495 2496 return propertyValueInt; 2497 } 2498 catch (final Exception e) 2499 { 2500 if (Debug.debugEnabled()) 2501 { 2502 Debug.debugException(e); 2503 Debug.debug(Level.WARNING, DebugType.OTHER, 2504 "Invalid value '" + propertyValueString + "' set for system " + 2505 "property '" + propertyName + "'. The value was expected " + 2506 "to be an integer. The default value of " + defaultValue + 2507 "will be used instead of the configured value.", 2508 e); 2509 } 2510 2511 return defaultValue; 2512 } 2513 } 2514 2515 2516 2517 /** 2518 * Retrieves the value of the specified system property as a long. 2519 * 2520 * @param propertyName The name of the system property whose value should be 2521 * retrieved. 2522 * @param defaultValue The default value that will be returned if the system 2523 * property is not defined or if its value cannot be 2524 * parsed as a long. 2525 * 2526 * @return The value of the specified system property as a long, or the 2527 * default value if the system property is not set with a valid 2528 * value. 2529 */ 2530 static Long getSystemProperty(final String propertyName, 2531 final Long defaultValue) 2532 { 2533 final String propertyValueString = System.getProperty(propertyName); 2534 if (propertyValueString == null) 2535 { 2536 if (Debug.debugEnabled()) 2537 { 2538 Debug.debug(Level.FINE, DebugType.OTHER, 2539 "Using the default value of " + defaultValue + " for system " + 2540 "property '" + propertyName + "' that is not set."); 2541 } 2542 2543 return defaultValue; 2544 } 2545 2546 try 2547 { 2548 final long propertyValueLong = Long.parseLong(propertyValueString); 2549 if (Debug.debugEnabled()) 2550 { 2551 Debug.debug(Level.INFO, DebugType.OTHER, 2552 "Using value " + propertyValueLong + " set for system property '" + 2553 propertyName + "'."); 2554 } 2555 2556 return propertyValueLong; 2557 } 2558 catch (final Exception e) 2559 { 2560 if (Debug.debugEnabled()) 2561 { 2562 Debug.debugException(e); 2563 Debug.debug(Level.WARNING, DebugType.OTHER, 2564 "Invalid value '" + propertyValueString + "' set for system " + 2565 "property '" + propertyName + "'. The value was expected " + 2566 "to be a long. The default value of " + defaultValue + 2567 "will be used instead of the configured value.", 2568 e); 2569 } 2570 2571 return defaultValue; 2572 } 2573 } 2574 2575 2576 2577 /** 2578 * Retrieves a string representation of this LDAP connection. 2579 * 2580 * @return A string representation of this LDAP connection. 2581 */ 2582 @Override() 2583 public String toString() 2584 { 2585 final StringBuilder buffer = new StringBuilder(); 2586 toString(buffer); 2587 return buffer.toString(); 2588 } 2589 2590 2591 2592 /** 2593 * Appends a string representation of this LDAP connection to the provided 2594 * buffer. 2595 * 2596 * @param buffer The buffer to which to append a string representation of 2597 * this LDAP connection. 2598 */ 2599 public void toString(final StringBuilder buffer) 2600 { 2601 buffer.append("LDAPConnectionOptions(autoReconnect="); 2602 buffer.append(autoReconnect); 2603 buffer.append(", nameResolver="); 2604 nameResolver.toString(buffer); 2605 buffer.append(", bindWithDNRequiresPassword="); 2606 buffer.append(bindWithDNRequiresPassword); 2607 buffer.append(", followReferrals="); 2608 buffer.append(followReferrals); 2609 if (followReferrals) 2610 { 2611 buffer.append(", referralHopLimit="); 2612 buffer.append(referralHopLimit); 2613 } 2614 if (referralConnector != null) 2615 { 2616 buffer.append(", referralConnectorClass="); 2617 buffer.append(referralConnector.getClass().getName()); 2618 } 2619 buffer.append(", useKeepAlive="); 2620 buffer.append(useKeepAlive); 2621 buffer.append(", useLinger="); 2622 if (useLinger) 2623 { 2624 buffer.append("true, lingerTimeoutSeconds="); 2625 buffer.append(lingerTimeoutSeconds); 2626 } 2627 else 2628 { 2629 buffer.append("false"); 2630 } 2631 buffer.append(", useReuseAddress="); 2632 buffer.append(useReuseAddress); 2633 buffer.append(", useSchema="); 2634 buffer.append(useSchema); 2635 buffer.append(", usePooledSchema="); 2636 buffer.append(usePooledSchema); 2637 buffer.append(", pooledSchemaTimeoutMillis="); 2638 buffer.append(pooledSchemaTimeoutMillis); 2639 buffer.append(", useSynchronousMode="); 2640 buffer.append(useSynchronousMode); 2641 buffer.append(", useTCPNoDelay="); 2642 buffer.append(useTCPNoDelay); 2643 buffer.append(", captureConnectStackTrace="); 2644 buffer.append(captureConnectStackTrace); 2645 buffer.append(", connectTimeoutMillis="); 2646 buffer.append(connectTimeoutMillis); 2647 buffer.append(", responseTimeoutMillis="); 2648 buffer.append(responseTimeoutMillis); 2649 2650 for (final Map.Entry<OperationType,Long> e : 2651 responseTimeoutMillisByOperationType.entrySet()) 2652 { 2653 buffer.append(", responseTimeoutMillis."); 2654 buffer.append(e.getKey().name()); 2655 buffer.append('='); 2656 buffer.append(e.getValue()); 2657 } 2658 2659 for (final Map.Entry<String,Long> e : 2660 responseTimeoutMillisByExtendedOperationType.entrySet()) 2661 { 2662 buffer.append(", responseTimeoutMillis.EXTENDED."); 2663 buffer.append(e.getKey()); 2664 buffer.append('='); 2665 buffer.append(e.getValue()); 2666 } 2667 2668 buffer.append(", abandonOnTimeout="); 2669 buffer.append(abandonOnTimeout); 2670 buffer.append(", maxMessageSizeBytes="); 2671 buffer.append(maxMessageSizeBytes); 2672 buffer.append(", receiveBufferSizeBytes="); 2673 buffer.append(receiveBufferSizeBytes); 2674 buffer.append(", sendBufferSizeBytes="); 2675 buffer.append(sendBufferSizeBytes); 2676 buffer.append(", allowConcurrentSocketFactoryUse="); 2677 buffer.append(allowConcurrentSocketFactoryUse); 2678 if (disconnectHandler != null) 2679 { 2680 buffer.append(", disconnectHandlerClass="); 2681 buffer.append(disconnectHandler.getClass().getName()); 2682 } 2683 if (unsolicitedNotificationHandler != null) 2684 { 2685 buffer.append(", unsolicitedNotificationHandlerClass="); 2686 buffer.append(unsolicitedNotificationHandler.getClass().getName()); 2687 } 2688 2689 buffer.append(", sslSocketVerifierClass='"); 2690 buffer.append(sslSocketVerifier.getClass().getName()); 2691 buffer.append('\''); 2692 2693 buffer.append(')'); 2694 } 2695}