001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2009-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk; 037 038 039 040import java.io.Closeable; 041import java.util.ArrayList; 042import java.util.Collection; 043import java.util.EnumSet; 044import java.util.List; 045import java.util.Set; 046import java.util.concurrent.TimeUnit; 047import java.util.concurrent.TimeoutException; 048 049import com.unboundid.asn1.ASN1OctetString; 050import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; 051import com.unboundid.ldap.sdk.schema.Schema; 052import com.unboundid.ldif.LDIFException; 053import com.unboundid.util.Debug; 054import com.unboundid.util.NotExtensible; 055import com.unboundid.util.NotNull; 056import com.unboundid.util.Nullable; 057import com.unboundid.util.StaticUtils; 058import com.unboundid.util.ThreadSafety; 059import com.unboundid.util.ThreadSafetyLevel; 060import com.unboundid.util.Validator; 061 062import static com.unboundid.ldap.sdk.LDAPMessages.*; 063 064 065 066/** 067 * This class provides the base class for LDAP connection pool implementations 068 * provided by the LDAP SDK for Java. 069 */ 070@NotExtensible() 071@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_NOT_THREADSAFE) 072public abstract class AbstractConnectionPool 073 implements FullLDAPInterface, Closeable 074{ 075 /** 076 * Closes this connection pool. All connections currently held in the pool 077 * that are not in use will be closed, and any outstanding connections will be 078 * automatically closed when they are released back to the pool. 079 */ 080 @Override() 081 public abstract void close(); 082 083 084 085 /** 086 * Closes this connection pool, optionally using multiple threads to close the 087 * connections in parallel. 088 * 089 * @param unbind Indicates whether to try to send an unbind request to 090 * the server before closing the connection. 091 * @param numThreads The number of threads to use when closing the 092 * connections. 093 */ 094 public abstract void close(boolean unbind, int numThreads); 095 096 097 098 /** 099 * Indicates whether this connection pool has been closed. 100 * 101 * @return {@code true} if this connection pool has been closed, or 102 * {@code false} if not. 103 */ 104 public abstract boolean isClosed(); 105 106 107 108 /** 109 * Retrieves an LDAP connection from the pool. 110 * 111 * @return The LDAP connection taken from the pool. 112 * 113 * @throws LDAPException If no connection is available, or a problem occurs 114 * while creating a new connection to return. 115 */ 116 @NotNull() 117 public abstract LDAPConnection getConnection() 118 throws LDAPException; 119 120 121 122 /** 123 * Releases the provided connection back to this pool. 124 * 125 * @param connection The connection to be released back to the pool. 126 */ 127 public abstract void releaseConnection(@NotNull LDAPConnection connection); 128 129 130 131 /** 132 * Indicates that the provided connection is no longer in use, but is also no 133 * longer fit for use. The provided connection will be terminated and a new 134 * connection will be created and added to the pool in its place. 135 * 136 * @param connection The defunct connection being released. 137 */ 138 public abstract void releaseDefunctConnection( 139 @NotNull LDAPConnection connection); 140 141 142 143 /** 144 * Releases the provided connection back to the pool after an exception has 145 * been encountered while processing an operation on that connection. The 146 * connection pool health check instance associated with this pool will be 147 * used to determine whether the provided connection is still valid and will 148 * either release it back for use in processing other operations on the 149 * connection or will terminate the connection and create a new one to take 150 * its place. 151 * 152 * @param connection The connection to be evaluated and released back to the 153 * pool or replaced with a new connection. 154 * @param exception The exception caught while processing an operation on 155 * the connection. 156 */ 157 public final void releaseConnectionAfterException( 158 @NotNull final LDAPConnection connection, 159 @NotNull final LDAPException exception) 160 { 161 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 162 163 try 164 { 165 healthCheck.ensureConnectionValidAfterException(connection, exception); 166 releaseConnection(connection); 167 } 168 catch (final LDAPException le) 169 { 170 Debug.debugException(le); 171 releaseDefunctConnection(connection); 172 } 173 } 174 175 176 177 /** 178 * Releases the provided connection as defunct and creates a new connection to 179 * replace it, if possible, optionally connected to a different directory 180 * server instance than the instance with which the original connection was 181 * established. 182 * 183 * @param connection The defunct connection to be replaced. 184 * 185 * @return The newly-created connection intended to replace the provided 186 * connection. 187 * 188 * @throws LDAPException If a problem is encountered while trying to create 189 * the new connection. Note that even if an exception 190 * is thrown, then the provided connection must have 191 * been properly released as defunct. 192 */ 193 @NotNull() 194 public abstract LDAPConnection replaceDefunctConnection( 195 @NotNull LDAPConnection connection) 196 throws LDAPException; 197 198 199 200 /** 201 * Attempts to replace the provided connection. However, if an exception is 202 * encountered while obtaining the new connection then an exception will be 203 * thrown based on the provided {@code Throwable} object. 204 * 205 * @param t The {@code Throwable} that was caught and prompted the 206 * connection to be replaced. 207 * @param connection The defunct connection to be replaced. 208 * 209 * @return The newly-created connection intended to replace the provided 210 * connection. 211 * 212 * @throws LDAPException If an exception is encountered while attempting to 213 * obtain the new connection. Note that this 214 * exception will be generated from the provided 215 * {@code Throwable} rather than based on the 216 * exception caught while trying to create the new 217 * connection. 218 */ 219 @NotNull() 220 private LDAPConnection replaceDefunctConnection(@NotNull final Throwable t, 221 @NotNull final LDAPConnection connection) 222 throws LDAPException 223 { 224 try 225 { 226 return replaceDefunctConnection(connection); 227 } 228 catch (final LDAPException le) 229 { 230 Debug.debugException(le); 231 232 if (t instanceof LDAPException) 233 { 234 throw (LDAPException) t; 235 } 236 else 237 { 238 throw new LDAPException(ResultCode.LOCAL_ERROR, 239 ERR_POOL_OP_EXCEPTION.get(StaticUtils.getExceptionMessage(t)), t); 240 } 241 } 242 } 243 244 245 246 /** 247 * Indicates whether attempts to process operations should be retried on a 248 * newly-created connection if the initial attempt fails in a manner that 249 * indicates that the connection used to process that request may no longer 250 * be valid. Only a single retry will be attempted for any operation. 251 * <BR><BR> 252 * Note that this only applies to methods used to process operations in the 253 * context pool (e.g., using methods that are part of {@link LDAPInterface}), 254 * and will not automatically be used for operations processed on connections 255 * checked out of the pool. 256 * <BR><BR> 257 * This method is provided for the purpose of backward compatibility, but new 258 * functionality has been added to control retry on a per-operation-type 259 * basis via the {@link #setRetryFailedOperationsDueToInvalidConnections(Set)} 260 * method. If retry is enabled for any operation type, then this method will 261 * return {@code true}, and it will only return {@code false} if retry should 262 * not be used for any operation type. To determine the operation types for 263 * which failed operations may be retried, use the 264 * {@link #getOperationTypesToRetryDueToInvalidConnections()} method. 265 * 266 * @return {@code true} if the connection pool should attempt to retry 267 * operations on a newly-created connection if they fail in a way 268 * that indicates the associated connection may no longer be usable, 269 * or {@code false} if operations should only be attempted once. 270 */ 271 public final boolean retryFailedOperationsDueToInvalidConnections() 272 { 273 return (! getOperationTypesToRetryDueToInvalidConnections().isEmpty()); 274 } 275 276 277 278 /** 279 * Retrieves the set of operation types for which operations should be 280 * retried if the initial attempt fails in a manner that indicates that the 281 * connection used to process the request may no longer be valid. 282 * 283 * @return The set of operation types for which operations should be 284 * retried if the initial attempt fails in a manner that indicates 285 * that the connection used to process the request may no longer be 286 * valid, or an empty set if retries should not be performed for any 287 * type of operation. 288 */ 289 @NotNull() 290 public abstract Set<OperationType> 291 getOperationTypesToRetryDueToInvalidConnections(); 292 293 294 295 /** 296 * Specifies whether attempts to process operations should be retried on a 297 * newly-created connection if the initial attempt fails in a manner that 298 * indicates that the connection used to process that request may no longer 299 * be valid. Only a single retry will be attempted for any operation. 300 * <BR><BR> 301 * Note that this only applies to methods used to process operations in the 302 * context pool (e.g., using methods that are part of {@link LDAPInterface}), 303 * and will not automatically be used for operations processed on connections 304 * checked out of the pool. 305 * <BR><BR> 306 * This method is provided for the purpose of backward compatibility, but new 307 * functionality has been added to control retry on a per-operation-type 308 * basis via the {@link #setRetryFailedOperationsDueToInvalidConnections(Set)} 309 * method. If this is called with a value of {@code true}, then retry will be 310 * enabled for all types of operations. If it is called with a value of 311 * {@code false}, then retry will be disabled for all types of operations. 312 * 313 * @param retryFailedOperationsDueToInvalidConnections 314 * Indicates whether attempts to process operations should be 315 * retried on a newly-created connection if they fail in a way 316 * that indicates the associated connection may no longer be 317 * usable. 318 */ 319 public final void setRetryFailedOperationsDueToInvalidConnections( 320 final boolean retryFailedOperationsDueToInvalidConnections) 321 { 322 if (retryFailedOperationsDueToInvalidConnections) 323 { 324 setRetryFailedOperationsDueToInvalidConnections( 325 EnumSet.allOf(OperationType.class)); 326 } 327 else 328 { 329 setRetryFailedOperationsDueToInvalidConnections( 330 EnumSet.noneOf(OperationType.class)); 331 } 332 } 333 334 335 336 /** 337 * Specifies the types of operations that should be retried on a newly-created 338 * connection if the initial attempt fails in a manner that indicates that 339 * the connection used to process the request may no longer be valid. Only a 340 * single retry will be attempted for any operation. 341 * <BR><BR> 342 * Note that this only applies to methods used to process operations in the 343 * context pool (e.g., using methods that are part of {@link LDAPInterface}), 344 * and will not automatically be used for operations processed on connections 345 * checked out of the pool. 346 * 347 * @param operationTypes The types of operations for which to retry failed 348 * operations if they fail in a way that indicates the 349 * associated connection may no longer be usable. It 350 * may be {@code null} or empty to indicate that no 351 * types of operations should be retried. 352 */ 353 public abstract void setRetryFailedOperationsDueToInvalidConnections( 354 @Nullable Set<OperationType> operationTypes); 355 356 357 358 /** 359 * Retrieves the number of connections that are currently available for use in 360 * this connection pool, if applicable. 361 * 362 * @return The number of connections that are currently available for use in 363 * this connection pool, or -1 if that is not applicable for this 364 * type of connection pool. 365 */ 366 public abstract int getCurrentAvailableConnections(); 367 368 369 370 /** 371 * Retrieves the maximum number of connections to be maintained in this 372 * connection pool, which is the maximum number of available connections that 373 * should be available at any time, if applicable. 374 * 375 * @return The number of connections to be maintained in this connection 376 * pool, or -1 if that is not applicable for this type of connection 377 * pool. 378 */ 379 public abstract int getMaximumAvailableConnections(); 380 381 382 383 /** 384 * Retrieves the set of statistics maintained for this LDAP connection pool. 385 * 386 * @return The set of statistics maintained for this LDAP connection pool. 387 */ 388 @NotNull() 389 public abstract LDAPConnectionPoolStatistics getConnectionPoolStatistics(); 390 391 392 393 /** 394 * Retrieves the user-friendly name that has been assigned to this connection 395 * pool. 396 * 397 * @return The user-friendly name that has been assigned to this connection 398 * pool, or {@code null} if none has been assigned. 399 */ 400 @Nullable() 401 public abstract String getConnectionPoolName(); 402 403 404 405 /** 406 * Specifies the user-friendly name that should be used for this connection 407 * pool. This name may be used in debugging to help identify the purpose of 408 * this connection pool. It will also be assigned to all connections 409 * associated with this connection pool. 410 * 411 * @param connectionPoolName The user-friendly name that should be used for 412 * this connection pool. 413 */ 414 public abstract void setConnectionPoolName( 415 @Nullable String connectionPoolName); 416 417 418 419 /** 420 * Retrieves the health check implementation for this connection pool. 421 * 422 * @return The health check implementation for this connection pool. 423 */ 424 @NotNull() 425 public abstract LDAPConnectionPoolHealthCheck getHealthCheck(); 426 427 428 429 /** 430 * Retrieves the length of time in milliseconds between periodic background 431 * health checks against the available connections in this pool. 432 * 433 * @return The length of time in milliseconds between the periodic background 434 * health checks against the available connections in this pool. 435 */ 436 public abstract long getHealthCheckIntervalMillis(); 437 438 439 440 /** 441 * Specifies the length of time in milliseconds between periodic background 442 * health checks against the available connections in this pool. 443 * 444 * @param healthCheckInterval The length of time in milliseconds between 445 * periodic background health checks against the 446 * available connections in this pool. The 447 * provided value must be greater than zero. 448 */ 449 public abstract void setHealthCheckIntervalMillis(long healthCheckInterval); 450 451 452 453 /** 454 * Performs a health check against all connections currently available in this 455 * connection pool. This should only be invoked by the connection pool health 456 * check thread. 457 */ 458 protected abstract void doHealthCheck(); 459 460 461 462 /** 463 * Retrieves the directory server root DSE using a connection from this 464 * connection pool. 465 * 466 * @return The directory server root DSE, or {@code null} if it is not 467 * available. 468 * 469 * @throws LDAPException If a problem occurs while attempting to retrieve 470 * the server root DSE. 471 */ 472 @Override() 473 @Nullable() 474 public final RootDSE getRootDSE() 475 throws LDAPException 476 { 477 final LDAPConnection conn = getConnection(); 478 479 try 480 { 481 final RootDSE rootDSE = conn.getRootDSE(); 482 releaseConnection(conn); 483 return rootDSE; 484 } 485 catch (final Throwable t) 486 { 487 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 488 489 // If we have gotten here, then we should retry the operation with a 490 // newly-created connection. 491 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 492 493 try 494 { 495 final RootDSE rootDSE = newConn.getRootDSE(); 496 releaseConnection(newConn); 497 return rootDSE; 498 } 499 catch (final Throwable t2) 500 { 501 throwLDAPException(t2, newConn); 502 } 503 504 // This return statement should never be reached. 505 return null; 506 } 507 } 508 509 510 511 /** 512 * Retrieves the directory server schema definitions using a connection from 513 * this connection pool, using the subschema subentry DN contained in the 514 * server's root DSE. For directory servers containing a single schema, this 515 * should be sufficient for all purposes. For servers with multiple schemas, 516 * it may be necessary to specify the DN of the target entry for which to 517 * obtain the associated schema. 518 * 519 * @return The directory server schema definitions, or {@code null} if the 520 * schema information could not be retrieved (e.g, the client does 521 * not have permission to read the server schema). 522 * 523 * @throws LDAPException If a problem occurs while attempting to retrieve 524 * the server schema. 525 */ 526 @Override() 527 @Nullable() 528 public final Schema getSchema() 529 throws LDAPException 530 { 531 return getSchema(""); 532 } 533 534 535 536 /** 537 * Retrieves the directory server schema definitions that govern the specified 538 * entry using a connection from this connection pool. The subschemaSubentry 539 * attribute will be retrieved from the target entry, and then the appropriate 540 * schema definitions will be loaded from the entry referenced by that 541 * attribute. This may be necessary to ensure correct behavior in servers 542 * that support multiple schemas. 543 * 544 * @param entryDN The DN of the entry for which to retrieve the associated 545 * schema definitions. It may be {@code null} or an empty 546 * string if the subschemaSubentry attribute should be 547 * retrieved from the server's root DSE. 548 * 549 * @return The directory server schema definitions, or {@code null} if the 550 * schema information could not be retrieved (e.g, the client does 551 * not have permission to read the server schema). 552 * 553 * @throws LDAPException If a problem occurs while attempting to retrieve 554 * the server schema. 555 */ 556 @Override() 557 @Nullable() 558 public final Schema getSchema(@Nullable final String entryDN) 559 throws LDAPException 560 { 561 final LDAPConnection conn = getConnection(); 562 563 try 564 { 565 final Schema schema = conn.getSchema(entryDN); 566 releaseConnection(conn); 567 return schema; 568 } 569 catch (final Throwable t) 570 { 571 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 572 573 // If we have gotten here, then we should retry the operation with a 574 // newly-created connection. 575 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 576 577 try 578 { 579 final Schema schema = newConn.getSchema(entryDN); 580 releaseConnection(newConn); 581 return schema; 582 } 583 catch (final Throwable t2) 584 { 585 throwLDAPException(t2, newConn); 586 } 587 588 // This return statement should never be reached. 589 return null; 590 } 591 } 592 593 594 595 /** 596 * Retrieves the entry with the specified DN using a connection from this 597 * connection pool. All user attributes will be requested in the entry to 598 * return. 599 * 600 * @param dn The DN of the entry to retrieve. It must not be {@code null}. 601 * 602 * @return The requested entry, or {@code null} if the target entry does not 603 * exist or no entry was returned (e.g., if the authenticated user 604 * does not have permission to read the target entry). 605 * 606 * @throws LDAPException If a problem occurs while sending the request or 607 * reading the response. 608 */ 609 @Override() 610 @Nullable() 611 public final SearchResultEntry getEntry(@NotNull final String dn) 612 throws LDAPException 613 { 614 return getEntry(dn, StaticUtils.NO_STRINGS); 615 } 616 617 618 619 /** 620 * Retrieves the entry with the specified DN using a connection from this 621 * connection pool. 622 * 623 * @param dn The DN of the entry to retrieve. It must not be 624 * {@code null}. 625 * @param attributes The set of attributes to request for the target entry. 626 * If it is {@code null}, then all user attributes will be 627 * requested. 628 * 629 * @return The requested entry, or {@code null} if the target entry does not 630 * exist or no entry was returned (e.g., if the authenticated user 631 * does not have permission to read the target entry). 632 * 633 * @throws LDAPException If a problem occurs while sending the request or 634 * reading the response. 635 */ 636 @Override() 637 @Nullable() 638 public final SearchResultEntry getEntry(@NotNull final String dn, 639 @Nullable final String... attributes) 640 throws LDAPException 641 { 642 final LDAPConnection conn = getConnection(); 643 644 try 645 { 646 final SearchResultEntry entry = conn.getEntry(dn, attributes); 647 releaseConnection(conn); 648 return entry; 649 } 650 catch (final Throwable t) 651 { 652 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 653 654 // If we have gotten here, then we should retry the operation with a 655 // newly-created connection. 656 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 657 658 try 659 { 660 final SearchResultEntry entry = newConn.getEntry(dn, attributes); 661 releaseConnection(newConn); 662 return entry; 663 } 664 catch (final Throwable t2) 665 { 666 throwLDAPException(t2, newConn); 667 } 668 669 // This return statement should never be reached. 670 return null; 671 } 672 } 673 674 675 676 /** 677 * Processes an add operation with the provided information using a connection 678 * from this connection pool. 679 * 680 * @param dn The DN of the entry to add. It must not be 681 * {@code null}. 682 * @param attributes The set of attributes to include in the entry to add. 683 * It must not be {@code null}. 684 * 685 * @return The result of processing the add operation. 686 * 687 * @throws LDAPException If the server rejects the add request, or if a 688 * problem is encountered while sending the request or 689 * reading the response. 690 */ 691 @Override() 692 @NotNull() 693 public final LDAPResult add(@NotNull final String dn, 694 @NotNull final Attribute... attributes) 695 throws LDAPException 696 { 697 return add(new AddRequest(dn, attributes)); 698 } 699 700 701 702 /** 703 * Processes an add operation with the provided information using a connection 704 * from this connection pool. 705 * 706 * @param dn The DN of the entry to add. It must not be 707 * {@code null}. 708 * @param attributes The set of attributes to include in the entry to add. 709 * It must not be {@code null}. 710 * 711 * @return The result of processing the add operation. 712 * 713 * @throws LDAPException If the server rejects the add request, or if a 714 * problem is encountered while sending the request or 715 * reading the response. 716 */ 717 @Override() 718 @NotNull() 719 public final LDAPResult add(@NotNull final String dn, 720 @NotNull final Collection<Attribute> attributes) 721 throws LDAPException 722 { 723 return add(new AddRequest(dn, attributes)); 724 } 725 726 727 728 /** 729 * Processes an add operation with the provided information using a connection 730 * from this connection pool. 731 * 732 * @param entry The entry to add. It must not be {@code null}. 733 * 734 * @return The result of processing the add operation. 735 * 736 * @throws LDAPException If the server rejects the add request, or if a 737 * problem is encountered while sending the request or 738 * reading the response. 739 */ 740 @Override() 741 @NotNull() 742 public final LDAPResult add(@NotNull final Entry entry) 743 throws LDAPException 744 { 745 return add(new AddRequest(entry)); 746 } 747 748 749 750 /** 751 * Processes an add operation with the provided information using a connection 752 * from this connection pool. 753 * 754 * @param ldifLines The lines that comprise an LDIF representation of the 755 * entry to add. It must not be empty or {@code null}. 756 * 757 * @return The result of processing the add operation. 758 * 759 * @throws LDIFException If the provided entry lines cannot be decoded as an 760 * entry in LDIF form. 761 * 762 * @throws LDAPException If the server rejects the add request, or if a 763 * problem is encountered while sending the request or 764 * reading the response. 765 */ 766 @Override() 767 @NotNull() 768 public final LDAPResult add(@NotNull final String... ldifLines) 769 throws LDIFException, LDAPException 770 { 771 return add(new AddRequest(ldifLines)); 772 } 773 774 775 776 /** 777 * Processes the provided add request using a connection from this connection 778 * pool. 779 * 780 * @param addRequest The add request to be processed. It must not be 781 * {@code null}. 782 * 783 * @return The result of processing the add operation. 784 * 785 * @throws LDAPException If the server rejects the add request, or if a 786 * problem is encountered while sending the request or 787 * reading the response. 788 */ 789 @Override() 790 @NotNull() 791 public final LDAPResult add(@NotNull final AddRequest addRequest) 792 throws LDAPException 793 { 794 final LDAPConnection conn = getConnection(); 795 796 try 797 { 798 final LDAPResult result = conn.add(addRequest); 799 releaseConnection(conn); 800 return result; 801 } 802 catch (final Throwable t) 803 { 804 throwLDAPExceptionIfShouldNotRetry(t, OperationType.ADD, conn); 805 806 // If we have gotten here, then we should retry the operation with a 807 // newly-created connection. 808 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 809 810 try 811 { 812 final LDAPResult result = newConn.add(addRequest); 813 releaseConnection(newConn); 814 return result; 815 } 816 catch (final Throwable t2) 817 { 818 throwLDAPException(t2, newConn); 819 } 820 821 // This return statement should never be reached. 822 return null; 823 } 824 } 825 826 827 828 /** 829 * Processes the provided add request using a connection from this connection 830 * pool. 831 * 832 * @param addRequest The add request to be processed. It must not be 833 * {@code null}. 834 * 835 * @return The result of processing the add operation. 836 * 837 * @throws LDAPException If the server rejects the add request, or if a 838 * problem is encountered while sending the request or 839 * reading the response. 840 */ 841 @Override() 842 @NotNull() 843 public final LDAPResult add(@NotNull final ReadOnlyAddRequest addRequest) 844 throws LDAPException 845 { 846 return add((AddRequest) addRequest); 847 } 848 849 850 851 /** 852 * Processes a simple bind request with the provided DN and password using a 853 * connection from this connection pool. Note that this will impact the state 854 * of the connection in the pool, and therefore this method should only be 855 * used if this connection pool is used exclusively for processing bind 856 * operations, or if the retain identity request control (a proprietary 857 * control for use with the Ping Identity, UnboundID, or Nokia/Alcatel-Lucent 858 * 8661 Directory Server) is included in the bind request to ensure that the 859 * authentication state is not impacted. 860 * 861 * @param bindDN The bind DN for the bind operation. 862 * @param password The password for the simple bind operation. 863 * 864 * @return The result of processing the bind operation. 865 * 866 * @throws LDAPException If the server rejects the bind request, or if a 867 * problem occurs while sending the request or reading 868 * the response. 869 */ 870 @NotNull() 871 public final BindResult bind(@Nullable final String bindDN, 872 @Nullable final String password) 873 throws LDAPException 874 { 875 return bind(new SimpleBindRequest(bindDN, password)); 876 } 877 878 879 880 /** 881 * Processes the provided bind request using a connection from this connection 882 * pool. Note that this will impact the state of the connection in the pool, 883 * and therefore this method should only be used if this connection pool is 884 * used exclusively for processing bind operations, or if the retain identity 885 * request control (a proprietary control for use with the Ping Identity, 886 * UnboundID, or Nokia/Alcatel-Lucent 8661 Directory Server) is included in 887 * the bind request to ensure that the authentication state is not impacted. 888 * 889 * @param bindRequest The bind request to be processed. It must not be 890 * {@code null}. 891 * 892 * @return The result of processing the bind operation. 893 * 894 * @throws LDAPException If the server rejects the bind request, or if a 895 * problem occurs while sending the request or reading 896 * the response. 897 */ 898 @NotNull 899 public final BindResult bind(@NotNull final BindRequest bindRequest) 900 throws LDAPException 901 { 902 final LDAPConnection conn = getConnection(); 903 904 try 905 { 906 final BindResult result = conn.bind(bindRequest); 907 releaseConnection(conn); 908 return result; 909 } 910 catch (final Throwable t) 911 { 912 throwLDAPExceptionIfShouldNotRetry(t, OperationType.BIND, conn); 913 914 // If we have gotten here, then we should retry the operation with a 915 // newly-created connection. 916 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 917 918 try 919 { 920 final BindResult result = newConn.bind(bindRequest); 921 releaseConnection(newConn); 922 return result; 923 } 924 catch (final Throwable t2) 925 { 926 throwLDAPException(t2, newConn); 927 } 928 929 // This return statement should never be reached. 930 return null; 931 } 932 } 933 934 935 936 /** 937 * Processes a compare operation with the provided information using a 938 * connection from this connection pool. 939 * 940 * @param dn The DN of the entry in which to make the 941 * comparison. It must not be {@code null}. 942 * @param attributeName The attribute name for which to make the 943 * comparison. It must not be {@code null}. 944 * @param assertionValue The assertion value to verify in the target entry. 945 * It must not be {@code null}. 946 * 947 * @return The result of processing the compare operation. 948 * 949 * @throws LDAPException If the server rejects the compare request, or if a 950 * problem is encountered while sending the request or 951 * reading the response. 952 */ 953 @Override() 954 @NotNull() 955 public final CompareResult compare(@NotNull final String dn, 956 @NotNull final String attributeName, 957 @NotNull final String assertionValue) 958 throws LDAPException 959 { 960 return compare(new CompareRequest(dn, attributeName, assertionValue)); 961 } 962 963 964 965 /** 966 * Processes the provided compare request using a connection from this 967 * connection pool. 968 * 969 * @param compareRequest The compare request to be processed. It must not 970 * be {@code null}. 971 * 972 * @return The result of processing the compare operation. 973 * 974 * @throws LDAPException If the server rejects the compare request, or if a 975 * problem is encountered while sending the request or 976 * reading the response. 977 */ 978 @Override() 979 @NotNull() 980 public final CompareResult compare( 981 @NotNull final CompareRequest compareRequest) 982 throws LDAPException 983 { 984 final LDAPConnection conn = getConnection(); 985 986 try 987 { 988 final CompareResult result = conn.compare(compareRequest); 989 releaseConnection(conn); 990 return result; 991 } 992 catch (final Throwable t) 993 { 994 throwLDAPExceptionIfShouldNotRetry(t, OperationType.COMPARE, conn); 995 996 // If we have gotten here, then we should retry the operation with a 997 // newly-created connection. 998 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 999 1000 try 1001 { 1002 final CompareResult result = newConn.compare(compareRequest); 1003 releaseConnection(newConn); 1004 return result; 1005 } 1006 catch (final Throwable t2) 1007 { 1008 throwLDAPException(t2, newConn); 1009 } 1010 1011 // This return statement should never be reached. 1012 return null; 1013 } 1014 } 1015 1016 1017 1018 /** 1019 * Processes the provided compare request using a connection from this 1020 * connection pool. 1021 * 1022 * @param compareRequest The compare request to be processed. It must not 1023 * be {@code null}. 1024 * 1025 * @return The result of processing the compare operation. 1026 * 1027 * @throws LDAPException If the server rejects the compare request, or if a 1028 * problem is encountered while sending the request or 1029 * reading the response. 1030 */ 1031 @Override() 1032 @NotNull() 1033 public final CompareResult compare( 1034 @NotNull final ReadOnlyCompareRequest compareRequest) 1035 throws LDAPException 1036 { 1037 return compare((CompareRequest) compareRequest); 1038 } 1039 1040 1041 1042 /** 1043 * Deletes the entry with the specified DN using a connection from this 1044 * connection pool. 1045 * 1046 * @param dn The DN of the entry to delete. It must not be {@code null}. 1047 * 1048 * @return The result of processing the delete operation. 1049 * 1050 * @throws LDAPException If the server rejects the delete request, or if a 1051 * problem is encountered while sending the request or 1052 * reading the response. 1053 */ 1054 @Override() 1055 @NotNull() 1056 public final LDAPResult delete(@NotNull final String dn) 1057 throws LDAPException 1058 { 1059 return delete(new DeleteRequest(dn)); 1060 } 1061 1062 1063 1064 /** 1065 * Processes the provided delete request using a connection from this 1066 * connection pool. 1067 * 1068 * @param deleteRequest The delete request to be processed. It must not be 1069 * {@code null}. 1070 * 1071 * @return The result of processing the delete operation. 1072 * 1073 * @throws LDAPException If the server rejects the delete request, or if a 1074 * problem is encountered while sending the request or 1075 * reading the response. 1076 */ 1077 @Override() 1078 @NotNull() 1079 public final LDAPResult delete(@NotNull final DeleteRequest deleteRequest) 1080 throws LDAPException 1081 { 1082 final LDAPConnection conn = getConnection(); 1083 1084 try 1085 { 1086 final LDAPResult result = conn.delete(deleteRequest); 1087 releaseConnection(conn); 1088 return result; 1089 } 1090 catch (final Throwable t) 1091 { 1092 throwLDAPExceptionIfShouldNotRetry(t, OperationType.DELETE, conn); 1093 1094 // If we have gotten here, then we should retry the operation with a 1095 // newly-created connection. 1096 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1097 1098 try 1099 { 1100 final LDAPResult result = newConn.delete(deleteRequest); 1101 releaseConnection(newConn); 1102 return result; 1103 } 1104 catch (final Throwable t2) 1105 { 1106 throwLDAPException(t2, newConn); 1107 } 1108 1109 // This return statement should never be reached. 1110 return null; 1111 } 1112 } 1113 1114 1115 1116 /** 1117 * Processes the provided delete request using a connection from this 1118 * connection pool. 1119 * 1120 * @param deleteRequest The delete request to be processed. It must not be 1121 * {@code null}. 1122 * 1123 * @return The result of processing the delete operation. 1124 * 1125 * @throws LDAPException If the server rejects the delete request, or if a 1126 * problem is encountered while sending the request or 1127 * reading the response. 1128 */ 1129 @Override() 1130 @NotNull() 1131 public final LDAPResult delete( 1132 @NotNull final ReadOnlyDeleteRequest deleteRequest) 1133 throws LDAPException 1134 { 1135 return delete((DeleteRequest) deleteRequest); 1136 } 1137 1138 1139 1140 /** 1141 * Processes an extended operation with the provided request OID using a 1142 * connection from this connection pool. Note that this method should not be 1143 * used to perform any operation that will alter the state of the connection 1144 * in the pool (e.g., a StartTLS operation) or that involves multiple 1145 * distinct operations on the same connection (e.g., LDAP transactions). 1146 * 1147 * @param requestOID The OID for the extended request to process. It must 1148 * not be {@code null}. 1149 * 1150 * @return The extended result object that provides information about the 1151 * result of the request processing. 1152 * 1153 * @throws LDAPException If a problem occurs while sending the request or 1154 * reading the response. 1155 */ 1156 @NotNull() 1157 public final ExtendedResult processExtendedOperation( 1158 @NotNull final String requestOID) 1159 throws LDAPException 1160 { 1161 return processExtendedOperation(new ExtendedRequest(requestOID)); 1162 } 1163 1164 1165 1166 /** 1167 * Processes an extended operation with the provided request OID and value 1168 * using a connection from this connection pool. Note that this method should 1169 * not be used to perform any operation that will alter the state of the 1170 * connection in the pool (e.g., a StartTLS operation) or that involves 1171 * multiple distinct operations on the same connection (e.g., LDAP 1172 * transactions). 1173 * 1174 * @param requestOID The OID for the extended request to process. It must 1175 * not be {@code null}. 1176 * @param requestValue The encoded value for the extended request to 1177 * process. It may be {@code null} if there does not 1178 * need to be a value for the requested operation. 1179 * 1180 * @return The extended result object that provides information about the 1181 * result of the request processing. 1182 * 1183 * @throws LDAPException If a problem occurs while sending the request or 1184 * reading the response. 1185 */ 1186 @NotNull() 1187 public final ExtendedResult processExtendedOperation( 1188 @NotNull final String requestOID, 1189 @Nullable final ASN1OctetString requestValue) 1190 throws LDAPException 1191 { 1192 return processExtendedOperation(new ExtendedRequest(requestOID, 1193 requestValue)); 1194 } 1195 1196 1197 1198 /** 1199 * Processes the provided extended request using a connection from this 1200 * connection pool. Note that this method should not be used to perform any 1201 * operation that will alter the state of the connection in the pool (e.g., a 1202 * StartTLS operation) or that involves multiple distinct operations on the 1203 * same connection (e.g., LDAP transactions). 1204 * 1205 * @param extendedRequest The extended request to be processed. It must not 1206 * be {@code null}. 1207 * 1208 * @return The extended result object that provides information about the 1209 * result of the request processing. 1210 * 1211 * @throws LDAPException If a problem occurs while sending the request or 1212 * reading the response. 1213 */ 1214 @NotNull() 1215 public final ExtendedResult processExtendedOperation( 1216 @NotNull final ExtendedRequest extendedRequest) 1217 throws LDAPException 1218 { 1219 if (extendedRequest.getOID().equals( 1220 StartTLSExtendedRequest.STARTTLS_REQUEST_OID)) 1221 { 1222 throw new LDAPException(ResultCode.NOT_SUPPORTED, 1223 ERR_POOL_STARTTLS_NOT_ALLOWED.get()); 1224 } 1225 1226 final LDAPConnection conn = getConnection(); 1227 1228 try 1229 { 1230 final ExtendedResult result = 1231 conn.processExtendedOperation(extendedRequest); 1232 releaseConnection(conn); 1233 return result; 1234 } 1235 catch (final Throwable t) 1236 { 1237 throwLDAPExceptionIfShouldNotRetry(t, OperationType.EXTENDED, conn); 1238 1239 // If we have gotten here, then we should retry the operation with a 1240 // newly-created connection. 1241 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1242 1243 try 1244 { 1245 final ExtendedResult result = 1246 newConn.processExtendedOperation(extendedRequest); 1247 releaseConnection(newConn); 1248 return result; 1249 } 1250 catch (final Throwable t2) 1251 { 1252 throwLDAPException(t2, newConn); 1253 } 1254 1255 // This return statement should never be reached. 1256 return null; 1257 } 1258 } 1259 1260 1261 1262 /** 1263 * Applies the provided modification to the specified entry using a connection 1264 * from this connection pool. 1265 * 1266 * @param dn The DN of the entry to modify. It must not be {@code null}. 1267 * @param mod The modification to apply to the target entry. It must not 1268 * be {@code null}. 1269 * 1270 * @return The result of processing the modify operation. 1271 * 1272 * @throws LDAPException If the server rejects the modify request, or if a 1273 * problem is encountered while sending the request or 1274 * reading the response. 1275 */ 1276 @Override() 1277 @NotNull() 1278 public final LDAPResult modify(@NotNull final String dn, 1279 @NotNull final Modification mod) 1280 throws LDAPException 1281 { 1282 return modify(new ModifyRequest(dn, mod)); 1283 } 1284 1285 1286 1287 /** 1288 * Applies the provided set of modifications to the specified entry using a 1289 * connection from this connection pool. 1290 * 1291 * @param dn The DN of the entry to modify. It must not be {@code null}. 1292 * @param mods The set of modifications to apply to the target entry. It 1293 * must not be {@code null} or empty. * 1294 * @return The result of processing the modify operation. 1295 * 1296 * @throws LDAPException If the server rejects the modify request, or if a 1297 * problem is encountered while sending the request or 1298 * reading the response. 1299 */ 1300 @Override() 1301 @NotNull() 1302 public final LDAPResult modify(@NotNull final String dn, 1303 @NotNull final Modification... mods) 1304 throws LDAPException 1305 { 1306 return modify(new ModifyRequest(dn, mods)); 1307 } 1308 1309 1310 1311 /** 1312 * Applies the provided set of modifications to the specified entry using a 1313 * connection from this connection pool. 1314 * 1315 * @param dn The DN of the entry to modify. It must not be {@code null}. 1316 * @param mods The set of modifications to apply to the target entry. It 1317 * must not be {@code null} or empty. 1318 * 1319 * @return The result of processing the modify operation. 1320 * 1321 * @throws LDAPException If the server rejects the modify request, or if a 1322 * problem is encountered while sending the request or 1323 * reading the response. 1324 */ 1325 @Override() 1326 @NotNull() 1327 public final LDAPResult modify(@NotNull final String dn, 1328 @NotNull final List<Modification> mods) 1329 throws LDAPException 1330 { 1331 return modify(new ModifyRequest(dn, mods)); 1332 } 1333 1334 1335 1336 /** 1337 * Processes a modify request from the provided LDIF representation of the 1338 * changes using a connection from this connection pool. 1339 * 1340 * @param ldifModificationLines The lines that comprise an LDIF 1341 * representation of a modify change record. 1342 * It must not be {@code null} or empty. 1343 * 1344 * @return The result of processing the modify operation. 1345 * 1346 * @throws LDIFException If the provided set of lines cannot be parsed as an 1347 * LDIF modify change record. 1348 * 1349 * @throws LDAPException If the server rejects the modify request, or if a 1350 * problem is encountered while sending the request or 1351 * reading the response. 1352 * 1353 */ 1354 @Override() 1355 @NotNull() 1356 public final LDAPResult modify(@NotNull final String... ldifModificationLines) 1357 throws LDIFException, LDAPException 1358 { 1359 return modify(new ModifyRequest(ldifModificationLines)); 1360 } 1361 1362 1363 1364 /** 1365 * Processes the provided modify request using a connection from this 1366 * connection pool. 1367 * 1368 * @param modifyRequest The modify request to be processed. It must not be 1369 * {@code null}. 1370 * 1371 * @return The result of processing the modify operation. 1372 * 1373 * @throws LDAPException If the server rejects the modify request, or if a 1374 * problem is encountered while sending the request or 1375 * reading the response. 1376 */ 1377 @Override() 1378 @NotNull() 1379 public final LDAPResult modify(@NotNull final ModifyRequest modifyRequest) 1380 throws LDAPException 1381 { 1382 final LDAPConnection conn = getConnection(); 1383 1384 try 1385 { 1386 final LDAPResult result = conn.modify(modifyRequest); 1387 releaseConnection(conn); 1388 return result; 1389 } 1390 catch (final Throwable t) 1391 { 1392 throwLDAPExceptionIfShouldNotRetry(t, OperationType.MODIFY, conn); 1393 1394 // If we have gotten here, then we should retry the operation with a 1395 // newly-created connection. 1396 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1397 1398 try 1399 { 1400 final LDAPResult result = newConn.modify(modifyRequest); 1401 releaseConnection(newConn); 1402 return result; 1403 } 1404 catch (final Throwable t2) 1405 { 1406 throwLDAPException(t2, newConn); 1407 } 1408 1409 // This return statement should never be reached. 1410 return null; 1411 } 1412 } 1413 1414 1415 1416 /** 1417 * Processes the provided modify request using a connection from this 1418 * connection pool. 1419 * 1420 * @param modifyRequest The modify request to be processed. It must not be 1421 * {@code null}. 1422 * 1423 * @return The result of processing the modify operation. 1424 * 1425 * @throws LDAPException If the server rejects the modify request, or if a 1426 * problem is encountered while sending the request or 1427 * reading the response. 1428 */ 1429 @Override() 1430 @NotNull() 1431 public final LDAPResult modify( 1432 @NotNull final ReadOnlyModifyRequest modifyRequest) 1433 throws LDAPException 1434 { 1435 return modify((ModifyRequest) modifyRequest); 1436 } 1437 1438 1439 1440 /** 1441 * Performs a modify DN operation with the provided information using a 1442 * connection from this connection pool. 1443 * 1444 * @param dn The current DN for the entry to rename. It must not 1445 * be {@code null}. 1446 * @param newRDN The new RDN to use for the entry. It must not be 1447 * {@code null}. 1448 * @param deleteOldRDN Indicates whether to delete the current RDN value 1449 * from the entry. 1450 * 1451 * @return The result of processing the modify DN operation. 1452 * 1453 * @throws LDAPException If the server rejects the modify DN request, or if 1454 * a problem is encountered while sending the request 1455 * or reading the response. 1456 */ 1457 @Override() 1458 @NotNull() 1459 public final LDAPResult modifyDN(@NotNull final String dn, 1460 @NotNull final String newRDN, 1461 final boolean deleteOldRDN) 1462 throws LDAPException 1463 { 1464 return modifyDN(new ModifyDNRequest(dn, newRDN, deleteOldRDN)); 1465 } 1466 1467 1468 1469 /** 1470 * Performs a modify DN operation with the provided information using a 1471 * connection from this connection pool. 1472 * 1473 * @param dn The current DN for the entry to rename. It must not 1474 * be {@code null}. 1475 * @param newRDN The new RDN to use for the entry. It must not be 1476 * {@code null}. 1477 * @param deleteOldRDN Indicates whether to delete the current RDN value 1478 * from the entry. 1479 * @param newSuperiorDN The new superior DN for the entry. It may be 1480 * {@code null} if the entry is not to be moved below a 1481 * new parent. 1482 * 1483 * @return The result of processing the modify DN operation. 1484 * 1485 * @throws LDAPException If the server rejects the modify DN request, or if 1486 * a problem is encountered while sending the request 1487 * or reading the response. 1488 */ 1489 @Override() 1490 @NotNull() 1491 public final LDAPResult modifyDN(@NotNull final String dn, 1492 @NotNull final String newRDN, 1493 final boolean deleteOldRDN, 1494 @Nullable final String newSuperiorDN) 1495 throws LDAPException 1496 { 1497 return modifyDN(new ModifyDNRequest(dn, newRDN, deleteOldRDN, 1498 newSuperiorDN)); 1499 } 1500 1501 1502 1503 /** 1504 * Processes the provided modify DN request using a connection from this 1505 * connection pool. 1506 * 1507 * @param modifyDNRequest The modify DN request to be processed. It must 1508 * not be {@code null}. 1509 * 1510 * @return The result of processing the modify DN operation. 1511 * 1512 * @throws LDAPException If the server rejects the modify DN request, or if 1513 * a problem is encountered while sending the request 1514 * or reading the response. 1515 */ 1516 @Override() 1517 @NotNull() 1518 public final LDAPResult modifyDN( 1519 @NotNull final ModifyDNRequest modifyDNRequest) 1520 throws LDAPException 1521 { 1522 final LDAPConnection conn = getConnection(); 1523 1524 try 1525 { 1526 final LDAPResult result = conn.modifyDN(modifyDNRequest); 1527 releaseConnection(conn); 1528 return result; 1529 } 1530 catch (final Throwable t) 1531 { 1532 throwLDAPExceptionIfShouldNotRetry(t, OperationType.MODIFY_DN, conn); 1533 1534 // If we have gotten here, then we should retry the operation with a 1535 // newly-created connection. 1536 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1537 1538 try 1539 { 1540 final LDAPResult result = newConn.modifyDN(modifyDNRequest); 1541 releaseConnection(newConn); 1542 return result; 1543 } 1544 catch (final Throwable t2) 1545 { 1546 throwLDAPException(t2, newConn); 1547 } 1548 1549 // This return statement should never be reached. 1550 return null; 1551 } 1552 } 1553 1554 1555 1556 /** 1557 * Processes the provided modify DN request using a connection from this 1558 * connection pool. 1559 * 1560 * @param modifyDNRequest The modify DN request to be processed. It must 1561 * not be {@code null}. 1562 * 1563 * @return The result of processing the modify DN operation. 1564 * 1565 * @throws LDAPException If the server rejects the modify DN request, or if 1566 * a problem is encountered while sending the request 1567 * or reading the response. 1568 */ 1569 @Override() 1570 @NotNull() 1571 public final LDAPResult modifyDN( 1572 @NotNull final ReadOnlyModifyDNRequest modifyDNRequest) 1573 throws LDAPException 1574 { 1575 return modifyDN((ModifyDNRequest) modifyDNRequest); 1576 } 1577 1578 1579 1580 /** 1581 * Processes a search operation with the provided information using a 1582 * connection from this connection pool. The search result entries and 1583 * references will be collected internally and included in the 1584 * {@code SearchResult} object that is returned. 1585 * <BR><BR> 1586 * Note that if the search does not complete successfully, an 1587 * {@code LDAPSearchException} will be thrown In some cases, one or more 1588 * search result entries or references may have been returned before the 1589 * failure response is received. In this case, the 1590 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1591 * {@code getSearchEntries}, {@code getReferenceCount}, and 1592 * {@code getSearchReferences} may be used to obtain information about those 1593 * entries and references. 1594 * 1595 * @param baseDN The base DN for the search request. It must not be 1596 * {@code null}. 1597 * @param scope The scope that specifies the range of entries that 1598 * should be examined for the search. 1599 * @param filter The string representation of the filter to use to 1600 * identify matching entries. It must not be 1601 * {@code null}. 1602 * @param attributes The set of attributes that should be returned in 1603 * matching entries. It may be {@code null} or empty if 1604 * the default attribute set (all user attributes) is to 1605 * be requested. 1606 * 1607 * @return A search result object that provides information about the 1608 * processing of the search, including the set of matching entries 1609 * and search references returned by the server. 1610 * 1611 * @throws LDAPSearchException If the search does not complete successfully, 1612 * or if a problem is encountered while parsing 1613 * the provided filter string, sending the 1614 * request, or reading the response. If one or 1615 * more entries or references were returned 1616 * before the failure was encountered, then the 1617 * {@code LDAPSearchException} object may be 1618 * examined to obtain information about those 1619 * entries and/or references. 1620 */ 1621 @Override() 1622 @NotNull() 1623 public final SearchResult search(@NotNull final String baseDN, 1624 @NotNull final SearchScope scope, 1625 @NotNull final String filter, 1626 @Nullable final String... attributes) 1627 throws LDAPSearchException 1628 { 1629 return search(new SearchRequest(baseDN, scope, parseFilter(filter), 1630 attributes)); 1631 } 1632 1633 1634 1635 /** 1636 * Processes a search operation with the provided information using a 1637 * connection from this connection pool. The search result entries and 1638 * references will be collected internally and included in the 1639 * {@code SearchResult} object that is returned. 1640 * <BR><BR> 1641 * Note that if the search does not complete successfully, an 1642 * {@code LDAPSearchException} will be thrown In some cases, one or more 1643 * search result entries or references may have been returned before the 1644 * failure response is received. In this case, the 1645 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1646 * {@code getSearchEntries}, {@code getReferenceCount}, and 1647 * {@code getSearchReferences} may be used to obtain information about those 1648 * entries and references. 1649 * 1650 * @param baseDN The base DN for the search request. It must not be 1651 * {@code null}. 1652 * @param scope The scope that specifies the range of entries that 1653 * should be examined for the search. 1654 * @param filter The filter to use to identify matching entries. It 1655 * must not be {@code null}. 1656 * @param attributes The set of attributes that should be returned in 1657 * matching entries. It may be {@code null} or empty if 1658 * the default attribute set (all user attributes) is to 1659 * be requested. 1660 * 1661 * @return A search result object that provides information about the 1662 * processing of the search, including the set of matching entries 1663 * and search references returned by the server. 1664 * 1665 * @throws LDAPSearchException If the search does not complete successfully, 1666 * or if a problem is encountered while sending 1667 * the request or reading the response. If one 1668 * or more entries or references were returned 1669 * before the failure was encountered, then the 1670 * {@code LDAPSearchException} object may be 1671 * examined to obtain information about those 1672 * entries and/or references. 1673 */ 1674 @Override() 1675 @NotNull() 1676 public final SearchResult search(@NotNull final String baseDN, 1677 @NotNull final SearchScope scope, 1678 @NotNull final Filter filter, 1679 @Nullable final String... attributes) 1680 throws LDAPSearchException 1681 { 1682 return search(new SearchRequest(baseDN, scope, filter, attributes)); 1683 } 1684 1685 1686 1687 /** 1688 * Processes a search operation with the provided information using a 1689 * connection from this connection pool. 1690 * <BR><BR> 1691 * Note that if the search does not complete successfully, an 1692 * {@code LDAPSearchException} will be thrown In some cases, one or more 1693 * search result entries or references may have been returned before the 1694 * failure response is received. In this case, the 1695 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1696 * {@code getSearchEntries}, {@code getReferenceCount}, and 1697 * {@code getSearchReferences} may be used to obtain information about those 1698 * entries and references (although if a search result listener was provided, 1699 * then it will have been used to make any entries and references available, 1700 * and they will not be available through the {@code getSearchEntries} and 1701 * {@code getSearchReferences} methods). 1702 * 1703 * @param searchResultListener The search result listener that should be 1704 * used to return results to the client. It may 1705 * be {@code null} if the search results should 1706 * be collected internally and returned in the 1707 * {@code SearchResult} object. 1708 * @param baseDN The base DN for the search request. It must 1709 * not be {@code null}. 1710 * @param scope The scope that specifies the range of entries 1711 * that should be examined for the search. 1712 * @param filter The string representation of the filter to 1713 * use to identify matching entries. It must 1714 * not be {@code null}. 1715 * @param attributes The set of attributes that should be returned 1716 * in matching entries. It may be {@code null} 1717 * or empty if the default attribute set (all 1718 * user attributes) is to be requested. 1719 * 1720 * @return A search result object that provides information about the 1721 * processing of the search, potentially including the set of 1722 * matching entries and search references returned by the server. 1723 * 1724 * @throws LDAPSearchException If the search does not complete successfully, 1725 * or if a problem is encountered while parsing 1726 * the provided filter string, sending the 1727 * request, or reading the response. If one 1728 * or more entries or references were returned 1729 * before the failure was encountered, then the 1730 * {@code LDAPSearchException} object may be 1731 * examined to obtain information about those 1732 * entries and/or references. 1733 */ 1734 @Override() 1735 @NotNull() 1736 public final SearchResult search( 1737 @Nullable final SearchResultListener searchResultListener, 1738 @NotNull final String baseDN, @NotNull final SearchScope scope, 1739 @NotNull final String filter, @Nullable final String... attributes) 1740 throws LDAPSearchException 1741 { 1742 return search(new SearchRequest(searchResultListener, baseDN, scope, 1743 parseFilter(filter), attributes)); 1744 } 1745 1746 1747 1748 /** 1749 * Processes a search operation with the provided information using a 1750 * connection from this connection pool. 1751 * <BR><BR> 1752 * Note that if the search does not complete successfully, an 1753 * {@code LDAPSearchException} will be thrown In some cases, one or more 1754 * search result entries or references may have been returned before the 1755 * failure response is received. In this case, the 1756 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1757 * {@code getSearchEntries}, {@code getReferenceCount}, and 1758 * {@code getSearchReferences} may be used to obtain information about those 1759 * entries and references (although if a search result listener was provided, 1760 * then it will have been used to make any entries and references available, 1761 * and they will not be available through the {@code getSearchEntries} and 1762 * {@code getSearchReferences} methods). 1763 * 1764 * @param searchResultListener The search result listener that should be 1765 * used to return results to the client. It may 1766 * be {@code null} if the search results should 1767 * be collected internally and returned in the 1768 * {@code SearchResult} object. 1769 * @param baseDN The base DN for the search request. It must 1770 * not be {@code null}. 1771 * @param scope The scope that specifies the range of entries 1772 * that should be examined for the search. 1773 * @param filter The filter to use to identify matching 1774 * entries. It must not be {@code null}. 1775 * @param attributes The set of attributes that should be returned 1776 * in matching entries. It may be {@code null} 1777 * or empty if the default attribute set (all 1778 * user attributes) is to be requested. 1779 * 1780 * @return A search result object that provides information about the 1781 * processing of the search, potentially including the set of 1782 * matching entries and search references returned by the server. 1783 * 1784 * @throws LDAPSearchException If the search does not complete successfully, 1785 * or if a problem is encountered while sending 1786 * the request or reading the response. If one 1787 * or more entries or references were returned 1788 * before the failure was encountered, then the 1789 * {@code LDAPSearchException} object may be 1790 * examined to obtain information about those 1791 * entries and/or references. 1792 */ 1793 @Override() 1794 @NotNull() 1795 public final SearchResult search( 1796 @Nullable final SearchResultListener searchResultListener, 1797 @NotNull final String baseDN, @NotNull final SearchScope scope, 1798 @NotNull final Filter filter, @Nullable final String... attributes) 1799 throws LDAPSearchException 1800 { 1801 return search(new SearchRequest(searchResultListener, baseDN, scope, 1802 filter, attributes)); 1803 } 1804 1805 1806 1807 /** 1808 * Processes a search operation with the provided information using a 1809 * connection from this connection pool. The search result entries and 1810 * references will be collected internally and included in the 1811 * {@code SearchResult} object that is returned. 1812 * <BR><BR> 1813 * Note that if the search does not complete successfully, an 1814 * {@code LDAPSearchException} will be thrown In some cases, one or more 1815 * search result entries or references may have been returned before the 1816 * failure response is received. In this case, the 1817 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1818 * {@code getSearchEntries}, {@code getReferenceCount}, and 1819 * {@code getSearchReferences} may be used to obtain information about those 1820 * entries and references. 1821 * 1822 * @param baseDN The base DN for the search request. It must not be 1823 * {@code null}. 1824 * @param scope The scope that specifies the range of entries that 1825 * should be examined for the search. 1826 * @param derefPolicy The dereference policy the server should use for any 1827 * aliases encountered while processing the search. 1828 * @param sizeLimit The maximum number of entries that the server should 1829 * return for the search. A value of zero indicates that 1830 * there should be no limit. 1831 * @param timeLimit The maximum length of time in seconds that the server 1832 * should spend processing this search request. A value 1833 * of zero indicates that there should be no limit. 1834 * @param typesOnly Indicates whether to return only attribute names in 1835 * matching entries, or both attribute names and values. 1836 * @param filter The string representation of the filter to use to 1837 * identify matching entries. It must not be 1838 * {@code null}. 1839 * @param attributes The set of attributes that should be returned in 1840 * matching entries. It may be {@code null} or empty if 1841 * the default attribute set (all user attributes) is to 1842 * be requested. 1843 * 1844 * @return A search result object that provides information about the 1845 * processing of the search, including the set of matching entries 1846 * and search references returned by the server. 1847 * 1848 * @throws LDAPSearchException If the search does not complete successfully, 1849 * or if a problem is encountered while parsing 1850 * the provided filter string, sending the 1851 * request, or reading the response. If one 1852 * or more entries or references were returned 1853 * before the failure was encountered, then the 1854 * {@code LDAPSearchException} object may be 1855 * examined to obtain information about those 1856 * entries and/or references. 1857 */ 1858 @Override() 1859 @NotNull() 1860 public final SearchResult search(@NotNull final String baseDN, 1861 @NotNull final SearchScope scope, 1862 @NotNull final DereferencePolicy derefPolicy, 1863 final int sizeLimit, final int timeLimit, 1864 final boolean typesOnly, 1865 @NotNull final String filter, 1866 @Nullable final String... attributes) 1867 throws LDAPSearchException 1868 { 1869 return search(new SearchRequest(baseDN, scope, derefPolicy, sizeLimit, 1870 timeLimit, typesOnly, parseFilter(filter), attributes)); 1871 } 1872 1873 1874 1875 /** 1876 * Processes a search operation with the provided information using a 1877 * connection from this connection pool. The search result entries and 1878 * references will be collected internally and included in the 1879 * {@code SearchResult} object that is returned. 1880 * <BR><BR> 1881 * Note that if the search does not complete successfully, an 1882 * {@code LDAPSearchException} will be thrown In some cases, one or more 1883 * search result entries or references may have been returned before the 1884 * failure response is received. In this case, the 1885 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1886 * {@code getSearchEntries}, {@code getReferenceCount}, and 1887 * {@code getSearchReferences} may be used to obtain information about those 1888 * entries and references. 1889 * 1890 * @param baseDN The base DN for the search request. It must not be 1891 * {@code null}. 1892 * @param scope The scope that specifies the range of entries that 1893 * should be examined for the search. 1894 * @param derefPolicy The dereference policy the server should use for any 1895 * aliases encountered while processing the search. 1896 * @param sizeLimit The maximum number of entries that the server should 1897 * return for the search. A value of zero indicates that 1898 * there should be no limit. 1899 * @param timeLimit The maximum length of time in seconds that the server 1900 * should spend processing this search request. A value 1901 * of zero indicates that there should be no limit. 1902 * @param typesOnly Indicates whether to return only attribute names in 1903 * matching entries, or both attribute names and values. 1904 * @param filter The filter to use to identify matching entries. It 1905 * must not be {@code null}. 1906 * @param attributes The set of attributes that should be returned in 1907 * matching entries. It may be {@code null} or empty if 1908 * the default attribute set (all user attributes) is to 1909 * be requested. 1910 * 1911 * @return A search result object that provides information about the 1912 * processing of the search, including the set of matching entries 1913 * and search references returned by the server. 1914 * 1915 * @throws LDAPSearchException If the search does not complete successfully, 1916 * or if a problem is encountered while sending 1917 * the request or reading the response. If one 1918 * or more entries or references were returned 1919 * before the failure was encountered, then the 1920 * {@code LDAPSearchException} object may be 1921 * examined to obtain information about those 1922 * entries and/or references. 1923 */ 1924 @Override() 1925 @NotNull() 1926 public final SearchResult search(@NotNull final String baseDN, 1927 @NotNull final SearchScope scope, 1928 @NotNull final DereferencePolicy derefPolicy, 1929 final int sizeLimit, final int timeLimit, 1930 final boolean typesOnly, 1931 @NotNull final Filter filter, 1932 @Nullable final String... attributes) 1933 throws LDAPSearchException 1934 { 1935 return search(new SearchRequest(baseDN, scope, derefPolicy, sizeLimit, 1936 timeLimit, typesOnly, filter, attributes)); 1937 } 1938 1939 1940 1941 /** 1942 * Processes a search operation with the provided information using a 1943 * connection from this connection pool. 1944 * <BR><BR> 1945 * Note that if the search does not complete successfully, an 1946 * {@code LDAPSearchException} will be thrown In some cases, one or more 1947 * search result entries or references may have been returned before the 1948 * failure response is received. In this case, the 1949 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1950 * {@code getSearchEntries}, {@code getReferenceCount}, and 1951 * {@code getSearchReferences} may be used to obtain information about those 1952 * entries and references (although if a search result listener was provided, 1953 * then it will have been used to make any entries and references available, 1954 * and they will not be available through the {@code getSearchEntries} and 1955 * {@code getSearchReferences} methods). 1956 * 1957 * @param searchResultListener The search result listener that should be 1958 * used to return results to the client. It may 1959 * be {@code null} if the search results should 1960 * be collected internally and returned in the 1961 * {@code SearchResult} object. 1962 * @param baseDN The base DN for the search request. It must 1963 * not be {@code null}. 1964 * @param scope The scope that specifies the range of entries 1965 * that should be examined for the search. 1966 * @param derefPolicy The dereference policy the server should use 1967 * for any aliases encountered while processing 1968 * the search. 1969 * @param sizeLimit The maximum number of entries that the server 1970 * should return for the search. A value of 1971 * zero indicates that there should be no limit. 1972 * @param timeLimit The maximum length of time in seconds that 1973 * the server should spend processing this 1974 * search request. A value of zero indicates 1975 * that there should be no limit. 1976 * @param typesOnly Indicates whether to return only attribute 1977 * names in matching entries, or both attribute 1978 * names and values. 1979 * @param filter The string representation of the filter to 1980 * use to identify matching entries. It must 1981 * not be {@code null}. 1982 * @param attributes The set of attributes that should be returned 1983 * in matching entries. It may be {@code null} 1984 * or empty if the default attribute set (all 1985 * user attributes) is to be requested. 1986 * 1987 * @return A search result object that provides information about the 1988 * processing of the search, potentially including the set of 1989 * matching entries and search references returned by the server. 1990 * 1991 * @throws LDAPSearchException If the search does not complete successfully, 1992 * or if a problem is encountered while parsing 1993 * the provided filter string, sending the 1994 * request, or reading the response. If one 1995 * or more entries or references were returned 1996 * before the failure was encountered, then the 1997 * {@code LDAPSearchException} object may be 1998 * examined to obtain information about those 1999 * entries and/or references. 2000 */ 2001 @Override() 2002 @NotNull() 2003 public final SearchResult search( 2004 @Nullable final SearchResultListener searchResultListener, 2005 @NotNull final String baseDN, @NotNull final SearchScope scope, 2006 @NotNull final DereferencePolicy derefPolicy, final int sizeLimit, 2007 final int timeLimit, final boolean typesOnly, 2008 @NotNull final String filter, @Nullable final String... attributes) 2009 throws LDAPSearchException 2010 { 2011 return search(new SearchRequest(searchResultListener, baseDN, scope, 2012 derefPolicy, sizeLimit, timeLimit, typesOnly, parseFilter(filter), 2013 attributes)); 2014 } 2015 2016 2017 2018 /** 2019 * Processes a search operation with the provided information using a 2020 * connection from this connection pool. 2021 * <BR><BR> 2022 * Note that if the search does not complete successfully, an 2023 * {@code LDAPSearchException} will be thrown In some cases, one or more 2024 * search result entries or references may have been returned before the 2025 * failure response is received. In this case, the 2026 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2027 * {@code getSearchEntries}, {@code getReferenceCount}, and 2028 * {@code getSearchReferences} may be used to obtain information about those 2029 * entries and references (although if a search result listener was provided, 2030 * then it will have been used to make any entries and references available, 2031 * and they will not be available through the {@code getSearchEntries} and 2032 * {@code getSearchReferences} methods). 2033 * 2034 * @param searchResultListener The search result listener that should be 2035 * used to return results to the client. It may 2036 * be {@code null} if the search results should 2037 * be collected internally and returned in the 2038 * {@code SearchResult} object. 2039 * @param baseDN The base DN for the search request. It must 2040 * not be {@code null}. 2041 * @param scope The scope that specifies the range of entries 2042 * that should be examined for the search. 2043 * @param derefPolicy The dereference policy the server should use 2044 * for any aliases encountered while processing 2045 * the search. 2046 * @param sizeLimit The maximum number of entries that the server 2047 * should return for the search. A value of 2048 * zero indicates that there should be no limit. 2049 * @param timeLimit The maximum length of time in seconds that 2050 * the server should spend processing this 2051 * search request. A value of zero indicates 2052 * that there should be no limit. 2053 * @param typesOnly Indicates whether to return only attribute 2054 * names in matching entries, or both attribute 2055 * names and values. 2056 * @param filter The filter to use to identify matching 2057 * entries. It must not be {@code null}. 2058 * @param attributes The set of attributes that should be returned 2059 * in matching entries. It may be {@code null} 2060 * or empty if the default attribute set (all 2061 * user attributes) is to be requested. 2062 * 2063 * @return A search result object that provides information about the 2064 * processing of the search, potentially including the set of 2065 * matching entries and search references returned by the server. 2066 * 2067 * @throws LDAPSearchException If the search does not complete successfully, 2068 * or if a problem is encountered while sending 2069 * the request or reading the response. If one 2070 * or more entries or references were returned 2071 * before the failure was encountered, then the 2072 * {@code LDAPSearchException} object may be 2073 * examined to obtain information about those 2074 * entries and/or references. 2075 */ 2076 @Override() 2077 @NotNull() 2078 public final SearchResult search( 2079 @Nullable final SearchResultListener searchResultListener, 2080 @NotNull final String baseDN, @NotNull final SearchScope scope, 2081 @NotNull final DereferencePolicy derefPolicy, final int sizeLimit, 2082 final int timeLimit, final boolean typesOnly, 2083 @NotNull final Filter filter, @Nullable final String... attributes) 2084 throws LDAPSearchException 2085 { 2086 return search(new SearchRequest(searchResultListener, baseDN, scope, 2087 derefPolicy, sizeLimit, timeLimit, typesOnly, filter, attributes)); 2088 } 2089 2090 2091 2092 /** 2093 * Processes the provided search request using a connection from this 2094 * connection pool. 2095 * <BR><BR> 2096 * Note that if the search does not complete successfully, an 2097 * {@code LDAPSearchException} will be thrown In some cases, one or more 2098 * search result entries or references may have been returned before the 2099 * failure response is received. In this case, the 2100 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2101 * {@code getSearchEntries}, {@code getReferenceCount}, and 2102 * {@code getSearchReferences} may be used to obtain information about those 2103 * entries and references (although if a search result listener was provided, 2104 * then it will have been used to make any entries and references available, 2105 * and they will not be available through the {@code getSearchEntries} and 2106 * {@code getSearchReferences} methods). 2107 * 2108 * @param searchRequest The search request to be processed. It must not be 2109 * {@code null}. 2110 * 2111 * @return A search result object that provides information about the 2112 * processing of the search, potentially including the set of 2113 * matching entries and search references returned by the server. 2114 * 2115 * @throws LDAPSearchException If the search does not complete successfully, 2116 * or if a problem is encountered while sending 2117 * the request or reading the response. If one 2118 * or more entries or references were returned 2119 * before the failure was encountered, then the 2120 * {@code LDAPSearchException} object may be 2121 * examined to obtain information about those 2122 * entries and/or references. 2123 */ 2124 @Override() 2125 @NotNull() 2126 public final SearchResult search(@NotNull final SearchRequest searchRequest) 2127 throws LDAPSearchException 2128 { 2129 final LDAPConnection conn; 2130 try 2131 { 2132 conn = getConnection(); 2133 } 2134 catch (final LDAPException le) 2135 { 2136 Debug.debugException(le); 2137 throw new LDAPSearchException(le); 2138 } 2139 2140 try 2141 { 2142 final SearchResult result = conn.search(searchRequest); 2143 releaseConnection(conn); 2144 return result; 2145 } 2146 catch (final Throwable t) 2147 { 2148 throwLDAPSearchExceptionIfShouldNotRetry(t, conn); 2149 2150 // If we have gotten here, then we should retry the operation with a 2151 // newly-created connection. 2152 final LDAPConnection newConn; 2153 try 2154 { 2155 newConn = replaceDefunctConnection(t, conn); 2156 } 2157 catch (final LDAPException le) 2158 { 2159 Debug.debugException(le); 2160 throw new LDAPSearchException(le); 2161 } 2162 2163 try 2164 { 2165 final SearchResult result = newConn.search(searchRequest); 2166 releaseConnection(newConn); 2167 return result; 2168 } 2169 catch (final Throwable t2) 2170 { 2171 throwLDAPSearchException(t2, newConn); 2172 } 2173 2174 // This return statement should never be reached. 2175 return null; 2176 } 2177 } 2178 2179 2180 2181 /** 2182 * Processes the provided search request using a connection from this 2183 * connection pool. 2184 * <BR><BR> 2185 * Note that if the search does not complete successfully, an 2186 * {@code LDAPSearchException} will be thrown In some cases, one or more 2187 * search result entries or references may have been returned before the 2188 * failure response is received. In this case, the 2189 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2190 * {@code getSearchEntries}, {@code getReferenceCount}, and 2191 * {@code getSearchReferences} may be used to obtain information about those 2192 * entries and references (although if a search result listener was provided, 2193 * then it will have been used to make any entries and references available, 2194 * and they will not be available through the {@code getSearchEntries} and 2195 * {@code getSearchReferences} methods). 2196 * 2197 * @param searchRequest The search request to be processed. It must not be 2198 * {@code null}. 2199 * 2200 * @return A search result object that provides information about the 2201 * processing of the search, potentially including the set of 2202 * matching entries and search references returned by the server. 2203 * 2204 * @throws LDAPSearchException If the search does not complete successfully, 2205 * or if a problem is encountered while sending 2206 * the request or reading the response. If one 2207 * or more entries or references were returned 2208 * before the failure was encountered, then the 2209 * {@code LDAPSearchException} object may be 2210 * examined to obtain information about those 2211 * entries and/or references. 2212 */ 2213 @Override() 2214 @NotNull() 2215 public final SearchResult search( 2216 @NotNull final ReadOnlySearchRequest searchRequest) 2217 throws LDAPSearchException 2218 { 2219 return search((SearchRequest) searchRequest); 2220 } 2221 2222 2223 2224 /** 2225 * Processes a search operation with the provided information using a 2226 * connection from this connection pool. It is expected that at most one 2227 * entry will be returned from the search, and that no additional content from 2228 * the successful search result (e.g., diagnostic message or response 2229 * controls) are needed. 2230 * <BR><BR> 2231 * Note that if the search does not complete successfully, an 2232 * {@code LDAPSearchException} will be thrown In some cases, one or more 2233 * search result entries or references may have been returned before the 2234 * failure response is received. In this case, the 2235 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2236 * {@code getSearchEntries}, {@code getReferenceCount}, and 2237 * {@code getSearchReferences} may be used to obtain information about those 2238 * entries and references. 2239 * 2240 * @param baseDN The base DN for the search request. It must not be 2241 * {@code null}. 2242 * @param scope The scope that specifies the range of entries that 2243 * should be examined for the search. 2244 * @param filter The string representation of the filter to use to 2245 * identify matching entries. It must not be 2246 * {@code null}. 2247 * @param attributes The set of attributes that should be returned in 2248 * matching entries. It may be {@code null} or empty if 2249 * the default attribute set (all user attributes) is to 2250 * be requested. 2251 * 2252 * @return The entry that was returned from the search, or {@code null} if no 2253 * entry was returned or the base entry does not exist. 2254 * 2255 * @throws LDAPSearchException If the search does not complete successfully, 2256 * if more than a single entry is returned, or 2257 * if a problem is encountered while parsing the 2258 * provided filter string, sending the request, 2259 * or reading the response. If one or more 2260 * entries or references were returned before 2261 * the failure was encountered, then the 2262 * {@code LDAPSearchException} object may be 2263 * examined to obtain information about those 2264 * entries and/or references. 2265 */ 2266 @Override() 2267 @Nullable() 2268 public final SearchResultEntry searchForEntry(@NotNull final String baseDN, 2269 @NotNull final SearchScope scope, 2270 @NotNull final String filter, 2271 @Nullable final String... attributes) 2272 throws LDAPSearchException 2273 { 2274 return searchForEntry(new SearchRequest(baseDN, scope, 2275 DereferencePolicy.NEVER, 1, 0, false, parseFilter(filter), 2276 attributes)); 2277 } 2278 2279 2280 2281 /** 2282 * Processes a search operation with the provided information using a 2283 * connection from this connection pool. It is expected that at most one 2284 * entry will be returned from the search, and that no additional content from 2285 * the successful search result (e.g., diagnostic message or response 2286 * controls) are needed. 2287 * <BR><BR> 2288 * Note that if the search does not complete successfully, an 2289 * {@code LDAPSearchException} will be thrown In some cases, one or more 2290 * search result entries or references may have been returned before the 2291 * failure response is received. In this case, the 2292 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2293 * {@code getSearchEntries}, {@code getReferenceCount}, and 2294 * {@code getSearchReferences} may be used to obtain information about those 2295 * entries and references. 2296 * 2297 * @param baseDN The base DN for the search request. It must not be 2298 * {@code null}. 2299 * @param scope The scope that specifies the range of entries that 2300 * should be examined for the search. 2301 * @param filter The string representation of the filter to use to 2302 * identify matching entries. It must not be 2303 * {@code null}. 2304 * @param attributes The set of attributes that should be returned in 2305 * matching entries. It may be {@code null} or empty if 2306 * the default attribute set (all user attributes) is to 2307 * be requested. 2308 * 2309 * @return The entry that was returned from the search, or {@code null} if no 2310 * entry was returned or the base entry does not exist. 2311 * 2312 * @throws LDAPSearchException If the search does not complete successfully, 2313 * if more than a single entry is returned, or 2314 * if a problem is encountered while parsing the 2315 * provided filter string, sending the request, 2316 * or reading the response. If one or more 2317 * entries or references were returned before 2318 * the failure was encountered, then the 2319 * {@code LDAPSearchException} object may be 2320 * examined to obtain information about those 2321 * entries and/or references. 2322 */ 2323 @Override() 2324 @Nullable() 2325 public final SearchResultEntry searchForEntry(@NotNull final String baseDN, 2326 @NotNull final SearchScope scope, 2327 @NotNull final Filter filter, 2328 @Nullable final String... attributes) 2329 throws LDAPSearchException 2330 { 2331 return searchForEntry(new SearchRequest(baseDN, scope, 2332 DereferencePolicy.NEVER, 1, 0, false, filter, attributes)); 2333 } 2334 2335 2336 2337 /** 2338 * Processes a search operation with the provided information using a 2339 * connection from this connection pool. It is expected that at most one 2340 * entry will be returned from the search, and that no additional content from 2341 * the successful search result (e.g., diagnostic message or response 2342 * controls) are needed. 2343 * <BR><BR> 2344 * Note that if the search does not complete successfully, an 2345 * {@code LDAPSearchException} will be thrown In some cases, one or more 2346 * search result entries or references may have been returned before the 2347 * failure response is received. In this case, the 2348 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2349 * {@code getSearchEntries}, {@code getReferenceCount}, and 2350 * {@code getSearchReferences} may be used to obtain information about those 2351 * entries and references. 2352 * 2353 * @param baseDN The base DN for the search request. It must not be 2354 * {@code null}. 2355 * @param scope The scope that specifies the range of entries that 2356 * should be examined for the search. 2357 * @param derefPolicy The dereference policy the server should use for any 2358 * aliases encountered while processing the search. 2359 * @param timeLimit The maximum length of time in seconds that the server 2360 * should spend processing this search request. A value 2361 * of zero indicates that there should be no limit. 2362 * @param typesOnly Indicates whether to return only attribute names in 2363 * matching entries, or both attribute names and values. 2364 * @param filter The string representation of the filter to use to 2365 * identify matching entries. It must not be 2366 * {@code null}. 2367 * @param attributes The set of attributes that should be returned in 2368 * matching entries. It may be {@code null} or empty if 2369 * the default attribute set (all user attributes) is to 2370 * be requested. 2371 * 2372 * @return The entry that was returned from the search, or {@code null} if no 2373 * entry was returned or the base entry does not exist. 2374 * 2375 * @throws LDAPSearchException If the search does not complete successfully, 2376 * if more than a single entry is returned, or 2377 * if a problem is encountered while parsing the 2378 * provided filter string, sending the request, 2379 * or reading the response. If one or more 2380 * entries or references were returned before 2381 * the failure was encountered, then the 2382 * {@code LDAPSearchException} object may be 2383 * examined to obtain information about those 2384 * entries and/or references. 2385 */ 2386 @Override() 2387 @Nullable() 2388 public final SearchResultEntry searchForEntry(@NotNull final String baseDN, 2389 @NotNull final SearchScope scope, 2390 @NotNull final DereferencePolicy derefPolicy, 2391 final int timeLimit, final boolean typesOnly, 2392 @NotNull final String filter, 2393 @Nullable final String... attributes) 2394 throws LDAPSearchException 2395 { 2396 return searchForEntry(new SearchRequest(baseDN, scope, derefPolicy, 1, 2397 timeLimit, typesOnly, parseFilter(filter), attributes)); 2398 } 2399 2400 2401 2402 /** 2403 * Processes a search operation with the provided information using a 2404 * connection from this connection pool. It is expected that at most one 2405 * entry will be returned from the search, and that no additional content from 2406 * the successful search result (e.g., diagnostic message or response 2407 * controls) are needed. 2408 * <BR><BR> 2409 * Note that if the search does not complete successfully, an 2410 * {@code LDAPSearchException} will be thrown In some cases, one or more 2411 * search result entries or references may have been returned before the 2412 * failure response is received. In this case, the 2413 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2414 * {@code getSearchEntries}, {@code getReferenceCount}, and 2415 * {@code getSearchReferences} may be used to obtain information about those 2416 * entries and references. 2417 * 2418 * @param baseDN The base DN for the search request. It must not be 2419 * {@code null}. 2420 * @param scope The scope that specifies the range of entries that 2421 * should be examined for the search. 2422 * @param derefPolicy The dereference policy the server should use for any 2423 * aliases encountered while processing the search. 2424 * @param timeLimit The maximum length of time in seconds that the server 2425 * should spend processing this search request. A value 2426 * of zero indicates that there should be no limit. 2427 * @param typesOnly Indicates whether to return only attribute names in 2428 * matching entries, or both attribute names and values. 2429 * @param filter The filter to use to identify matching entries. It 2430 * must not be {@code null}. 2431 * @param attributes The set of attributes that should be returned in 2432 * matching entries. It may be {@code null} or empty if 2433 * the default attribute set (all user attributes) is to 2434 * be requested. 2435 * 2436 * @return The entry that was returned from the search, or {@code null} if no 2437 * entry was returned or the base entry does not exist. 2438 * 2439 * @throws LDAPSearchException If the search does not complete successfully, 2440 * if more than a single entry is returned, or 2441 * if a problem is encountered while parsing the 2442 * provided filter string, sending the request, 2443 * or reading the response. If one or more 2444 * entries or references were returned before 2445 * the failure was encountered, then the 2446 * {@code LDAPSearchException} object may be 2447 * examined to obtain information about those 2448 * entries and/or references. 2449 */ 2450 @Override() 2451 @Nullable() 2452 public final SearchResultEntry searchForEntry( 2453 @NotNull final String baseDN, 2454 @NotNull final SearchScope scope, 2455 @NotNull final DereferencePolicy derefPolicy, 2456 final int timeLimit, final boolean typesOnly, 2457 @NotNull final Filter filter, 2458 @Nullable final String... attributes) 2459 throws LDAPSearchException 2460 { 2461 return searchForEntry(new SearchRequest(baseDN, scope, derefPolicy, 1, 2462 timeLimit, typesOnly, filter, attributes)); 2463 } 2464 2465 2466 2467 /** 2468 * Processes a search operation with the provided information using a 2469 * connection from this connection pool. It is expected that at most one 2470 * entry will be returned from the search, and that no additional content from 2471 * the successful search result (e.g., diagnostic message or response 2472 * controls) are needed. 2473 * <BR><BR> 2474 * Note that if the search does not complete successfully, an 2475 * {@code LDAPSearchException} will be thrown In some cases, one or more 2476 * search result entries or references may have been returned before the 2477 * failure response is received. In this case, the 2478 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2479 * {@code getSearchEntries}, {@code getReferenceCount}, and 2480 * {@code getSearchReferences} may be used to obtain information about those 2481 * entries and references. 2482 * 2483 * @param searchRequest The search request to be processed. If it is 2484 * configured with a search result listener or a size 2485 * limit other than one, then the provided request will 2486 * be duplicated with the appropriate settings. 2487 * 2488 * @return The entry that was returned from the search, or {@code null} if no 2489 * entry was returned or the base entry does not exist. 2490 * 2491 * @throws LDAPSearchException If the search does not complete successfully, 2492 * if more than a single entry is returned, or 2493 * if a problem is encountered while parsing the 2494 * provided filter string, sending the request, 2495 * or reading the response. If one or more 2496 * entries or references were returned before 2497 * the failure was encountered, then the 2498 * {@code LDAPSearchException} object may be 2499 * examined to obtain information about those 2500 * entries and/or references. 2501 */ 2502 @Override() 2503 @Nullable() 2504 public final SearchResultEntry searchForEntry( 2505 @NotNull final SearchRequest searchRequest) 2506 throws LDAPSearchException 2507 { 2508 final LDAPConnection conn; 2509 try 2510 { 2511 conn = getConnection(); 2512 } 2513 catch (final LDAPException le) 2514 { 2515 Debug.debugException(le); 2516 throw new LDAPSearchException(le); 2517 } 2518 2519 try 2520 { 2521 final SearchResultEntry entry = conn.searchForEntry(searchRequest); 2522 releaseConnection(conn); 2523 return entry; 2524 } 2525 catch (final Throwable t) 2526 { 2527 throwLDAPSearchExceptionIfShouldNotRetry(t, conn); 2528 2529 // If we have gotten here, then we should retry the operation with a 2530 // newly-created connection. 2531 final LDAPConnection newConn; 2532 try 2533 { 2534 newConn = replaceDefunctConnection(t, conn); 2535 } 2536 catch (final LDAPException le) 2537 { 2538 Debug.debugException(le); 2539 throw new LDAPSearchException(le); 2540 } 2541 2542 try 2543 { 2544 final SearchResultEntry entry = newConn.searchForEntry(searchRequest); 2545 releaseConnection(newConn); 2546 return entry; 2547 } 2548 catch (final Throwable t2) 2549 { 2550 throwLDAPSearchException(t2, newConn); 2551 } 2552 2553 // This return statement should never be reached. 2554 return null; 2555 } 2556 } 2557 2558 2559 2560 /** 2561 * Processes a search operation with the provided information using a 2562 * connection from this connection pool. It is expected that at most one 2563 * entry will be returned from the search, and that no additional content from 2564 * the successful search result (e.g., diagnostic message or response 2565 * controls) are needed. 2566 * <BR><BR> 2567 * Note that if the search does not complete successfully, an 2568 * {@code LDAPSearchException} will be thrown In some cases, one or more 2569 * search result entries or references may have been returned before the 2570 * failure response is received. In this case, the 2571 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2572 * {@code getSearchEntries}, {@code getReferenceCount}, and 2573 * {@code getSearchReferences} may be used to obtain information about those 2574 * entries and references. 2575 * 2576 * @param searchRequest The search request to be processed. If it is 2577 * configured with a search result listener or a size 2578 * limit other than one, then the provided request will 2579 * be duplicated with the appropriate settings. 2580 * 2581 * @return The entry that was returned from the search, or {@code null} if no 2582 * entry was returned or the base entry does not exist. 2583 * 2584 * @throws LDAPSearchException If the search does not complete successfully, 2585 * if more than a single entry is returned, or 2586 * if a problem is encountered while parsing the 2587 * provided filter string, sending the request, 2588 * or reading the response. If one or more 2589 * entries or references were returned before 2590 * the failure was encountered, then the 2591 * {@code LDAPSearchException} object may be 2592 * examined to obtain information about those 2593 * entries and/or references. 2594 */ 2595 @Override() 2596 @Nullable() 2597 public final SearchResultEntry searchForEntry( 2598 @NotNull final ReadOnlySearchRequest searchRequest) 2599 throws LDAPSearchException 2600 { 2601 return searchForEntry((SearchRequest) searchRequest); 2602 } 2603 2604 2605 2606 /** 2607 * Parses the provided string as a {@code Filter} object. 2608 * 2609 * @param filterString The string to parse as a {@code Filter}. 2610 * 2611 * @return The parsed {@code Filter}. 2612 * 2613 * @throws LDAPSearchException If the provided string does not represent a 2614 * valid search filter. 2615 */ 2616 @NotNull() 2617 private static Filter parseFilter(@NotNull final String filterString) 2618 throws LDAPSearchException 2619 { 2620 try 2621 { 2622 return Filter.create(filterString); 2623 } 2624 catch (final LDAPException le) 2625 { 2626 Debug.debugException(le); 2627 throw new LDAPSearchException(le); 2628 } 2629 } 2630 2631 2632 2633 /** 2634 * Processes multiple requests in the order they are provided over a single 2635 * connection from this pool. Note that the 2636 * {@link #retryFailedOperationsDueToInvalidConnections()} setting will be 2637 * ignored when processing the provided operations, so that any failed 2638 * operations will not be retried. 2639 * 2640 * @param requests The list of requests to be processed. It must not 2641 * be {@code null} or empty. 2642 * @param continueOnError Indicates whether to attempt to process subsequent 2643 * requests if any of the operations does not 2644 * complete successfully. 2645 * 2646 * @return The set of results from the requests that were processed. The 2647 * order of result objects will correspond to the order of the 2648 * request objects, although the list of results may contain fewer 2649 * elements than the list of requests if an error occurred during 2650 * processing and {@code continueOnError} is {@code false}. 2651 * 2652 * @throws LDAPException If a problem occurs while trying to obtain a 2653 * connection to use for the requests. 2654 */ 2655 @NotNull() 2656 public final List<LDAPResult> processRequests( 2657 @NotNull final List<LDAPRequest> requests, 2658 final boolean continueOnError) 2659 throws LDAPException 2660 { 2661 Validator.ensureNotNull(requests); 2662 Validator.ensureFalse(requests.isEmpty(), 2663 "LDAPConnectionPool.processRequests.requests must not be empty."); 2664 2665 final LDAPConnection conn; 2666 try 2667 { 2668 conn = getConnection(); 2669 } 2670 catch (final LDAPException le) 2671 { 2672 Debug.debugException(le); 2673 throw new LDAPSearchException(le); 2674 } 2675 2676 final ArrayList<LDAPResult> results = new ArrayList<>(requests.size()); 2677 boolean isDefunct = false; 2678 2679 try 2680 { 2681requestLoop: 2682 for (final LDAPRequest request : requests) 2683 { 2684 try 2685 { 2686 final LDAPResult result = conn.processOperation(request); 2687 results.add(result); 2688 switch (result.getResultCode().intValue()) 2689 { 2690 case ResultCode.SUCCESS_INT_VALUE: 2691 case ResultCode.COMPARE_FALSE_INT_VALUE: 2692 case ResultCode.COMPARE_TRUE_INT_VALUE: 2693 case ResultCode.NO_OPERATION_INT_VALUE: 2694 // These will be considered successful operations. 2695 break; 2696 2697 default: 2698 // Anything else will be considered a failure. 2699 if (! ResultCode.isConnectionUsable(result.getResultCode())) 2700 { 2701 isDefunct = true; 2702 } 2703 2704 if (! continueOnError) 2705 { 2706 break requestLoop; 2707 } 2708 break; 2709 } 2710 } 2711 catch (final LDAPException le) 2712 { 2713 Debug.debugException(le); 2714 results.add(new LDAPResult(request.getLastMessageID(), 2715 le.getResultCode(), le.getMessage(), 2716 le.getMatchedDN(), le.getReferralURLs(), 2717 le.getResponseControls())); 2718 2719 if (! ResultCode.isConnectionUsable(le.getResultCode())) 2720 { 2721 isDefunct = true; 2722 } 2723 2724 if (! continueOnError) 2725 { 2726 break; 2727 } 2728 } 2729 } 2730 } 2731 finally 2732 { 2733 if (isDefunct) 2734 { 2735 releaseDefunctConnection(conn); 2736 } 2737 else 2738 { 2739 releaseConnection(conn); 2740 } 2741 } 2742 2743 return results; 2744 } 2745 2746 2747 2748 /** 2749 * Processes multiple requests over a single connection from this pool using 2750 * asynchronous processing to cause the operations to be processed 2751 * concurrently. The list of requests may contain only add, compare, delete, 2752 * modify, modify DN, and search operations (and any search operations to be 2753 * processed must be configured with an {@link AsyncSearchResultListener}. 2754 * This method will not return until all operations have completed, or until 2755 * the specified timeout period has elapsed. The order of elements in the 2756 * list of the {@link AsyncRequestID} objects returned will correspond to the 2757 * order of elements in the list of requests. The operation results may be 2758 * obtained from the returned {@code AsyncRequestID} objects using the 2759 * {@code java.util.concurrent.Future} API. 2760 * 2761 * @param requests The list of requests to be processed. It must 2762 * not be {@code null} or empty, and it must 2763 * contain only add, compare, modify, modify DN, 2764 * and search requests. Any search requests must 2765 * be configured with an 2766 * {@code AsyncSearchResultListener}. 2767 * @param maxWaitTimeMillis The maximum length of time in milliseconds to 2768 * wait for the operations to complete before 2769 * returning. A value that is less than or equal 2770 * to zero indicates that the client should wait 2771 * indefinitely for the operations to complete. 2772 * 2773 * @return The list of {@code AsyncRequestID} objects that may be used to 2774 * retrieve the results for the operations. The order of elements in 2775 * this list will correspond to the order of the provided requests. 2776 * 2777 * @throws LDAPException If there is a problem with any of the requests, or 2778 * if connections in the pool are configured to use 2779 * synchronous mode and therefore cannot be used to 2780 * process asynchronous operations. 2781 */ 2782 @NotNull() 2783 public final List<AsyncRequestID> processRequestsAsync( 2784 @NotNull final List<LDAPRequest> requests, 2785 final long maxWaitTimeMillis) 2786 throws LDAPException 2787 { 2788 // Make sure the set of requests is not null or empty. 2789 Validator.ensureNotNull(requests); 2790 Validator.ensureFalse(requests.isEmpty(), 2791 "LDAPConnectionPool.processRequests.requests must not be empty."); 2792 2793 // Make sure that all the requests are acceptable. 2794 for (final LDAPRequest r : requests) 2795 { 2796 switch (r.getOperationType()) 2797 { 2798 case ADD: 2799 case COMPARE: 2800 case DELETE: 2801 case MODIFY: 2802 case MODIFY_DN: 2803 // These operation types are always acceptable for asynchronous 2804 // processing. 2805 break; 2806 2807 case SEARCH: 2808 // Search operations will only be acceptable if they have been 2809 // configured with an async search result listener. 2810 final SearchRequest searchRequest = (SearchRequest) r; 2811 if ((searchRequest.getSearchResultListener() == null) || 2812 (! (searchRequest.getSearchResultListener() instanceof 2813 AsyncSearchResultListener))) 2814 { 2815 throw new LDAPException(ResultCode.PARAM_ERROR, 2816 ERR_POOL_PROCESS_REQUESTS_ASYNC_SEARCH_NOT_ASYNC.get( 2817 String.valueOf(r))); 2818 } 2819 break; 2820 2821 case ABANDON: 2822 case BIND: 2823 case EXTENDED: 2824 case UNBIND: 2825 default: 2826 // These operation types are never acceptable for asynchronous 2827 // processing. 2828 throw new LDAPException(ResultCode.PARAM_ERROR, 2829 ERR_POOL_PROCESS_REQUESTS_ASYNC_OP_NOT_ASYNC.get( 2830 String.valueOf(r))); 2831 } 2832 } 2833 2834 2835 final LDAPConnection conn; 2836 try 2837 { 2838 conn = getConnection(); 2839 } 2840 catch (final LDAPException le) 2841 { 2842 Debug.debugException(le); 2843 throw new LDAPSearchException(le); 2844 } 2845 2846 2847 final ArrayList<AsyncRequestID> requestIDs = 2848 new ArrayList<>(requests.size()); 2849 boolean isDefunct = false; 2850 2851 try 2852 { 2853 // Make sure that the connection is not configured to use synchronous 2854 // mode, because asynchronous operations are not allowed in that mode. 2855 if (conn.synchronousMode()) 2856 { 2857 throw new LDAPException(ResultCode.PARAM_ERROR, 2858 ERR_POOL_PROCESS_REQUESTS_ASYNC_SYNCHRONOUS_MODE.get()); 2859 } 2860 2861 2862 // Issue all of the requests. If an exception is encountered while 2863 // issuing a request, then convert it into an AsyncRequestID with the 2864 // exception as the result. 2865 for (final LDAPRequest r : requests) 2866 { 2867 AsyncRequestID requestID = null; 2868 try 2869 { 2870 switch (r.getOperationType()) 2871 { 2872 case ADD: 2873 requestID = conn.asyncAdd((AddRequest) r, null); 2874 break; 2875 case COMPARE: 2876 requestID = conn.asyncCompare((CompareRequest) r, null); 2877 break; 2878 case DELETE: 2879 requestID = conn.asyncDelete((DeleteRequest) r, null); 2880 break; 2881 case MODIFY: 2882 requestID = conn.asyncModify((ModifyRequest) r, null); 2883 break; 2884 case MODIFY_DN: 2885 requestID = conn.asyncModifyDN((ModifyDNRequest) r, null); 2886 break; 2887 case SEARCH: 2888 requestID = conn.asyncSearch((SearchRequest) r); 2889 break; 2890 } 2891 } 2892 catch (final LDAPException le) 2893 { 2894 Debug.debugException(le); 2895 requestID = new AsyncRequestID(r.getLastMessageID(), conn); 2896 requestID.setResult(le.toLDAPResult()); 2897 } 2898 2899 requestIDs.add(requestID); 2900 } 2901 2902 2903 // Wait for the operations to complete. If any operation does not 2904 // complete before the specified timeout, then create a failure result for 2905 // it. If any operation does not complete successfully, then attempt to 2906 // determine whether the failure may indicate that the connection is no 2907 // longer valid. 2908 final long startWaitingTime = System.currentTimeMillis(); 2909 final long stopWaitingTime; 2910 if (maxWaitTimeMillis > 0) 2911 { 2912 stopWaitingTime = startWaitingTime + maxWaitTimeMillis; 2913 } 2914 else 2915 { 2916 stopWaitingTime = Long.MAX_VALUE; 2917 } 2918 2919 for (final AsyncRequestID requestID : requestIDs) 2920 { 2921 LDAPResult result; 2922 final long waitTime = stopWaitingTime - System.currentTimeMillis(); 2923 if (waitTime > 0) 2924 { 2925 try 2926 { 2927 result = requestID.get(waitTime, TimeUnit.MILLISECONDS); 2928 } 2929 catch (final Exception e) 2930 { 2931 Debug.debugException(e); 2932 requestID.cancel(true); 2933 2934 if (e instanceof TimeoutException) 2935 { 2936 result = new LDAPResult(requestID.getMessageID(), 2937 ResultCode.TIMEOUT, 2938 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_TIMEOUT.get( 2939 (System.currentTimeMillis() - startWaitingTime)), 2940 null, StaticUtils.NO_STRINGS, StaticUtils.NO_CONTROLS); 2941 } 2942 else 2943 { 2944 result = new LDAPResult(requestID.getMessageID(), 2945 ResultCode.LOCAL_ERROR, 2946 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_EXCEPTION.get( 2947 StaticUtils.getExceptionMessage(e)), 2948 null, StaticUtils.NO_STRINGS, StaticUtils.NO_CONTROLS); 2949 } 2950 requestID.setResult(result); 2951 } 2952 } 2953 else 2954 { 2955 requestID.cancel(true); 2956 result = new LDAPResult(requestID.getMessageID(), 2957 ResultCode.TIMEOUT, 2958 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_TIMEOUT.get( 2959 (System.currentTimeMillis() - startWaitingTime)), 2960 null, StaticUtils.NO_STRINGS, StaticUtils.NO_CONTROLS); 2961 requestID.setResult(result); 2962 } 2963 2964 2965 // See if we think that the connection may be defunct. 2966 if (! ResultCode.isConnectionUsable(result.getResultCode())) 2967 { 2968 isDefunct = true; 2969 } 2970 } 2971 2972 return requestIDs; 2973 } 2974 finally 2975 { 2976 if (isDefunct) 2977 { 2978 releaseDefunctConnection(conn); 2979 } 2980 else 2981 { 2982 releaseConnection(conn); 2983 } 2984 } 2985 } 2986 2987 2988 2989 /** 2990 * Examines the provided {@code Throwable} object to determine whether it 2991 * represents an {@code LDAPException} that indicates the associated 2992 * connection may no longer be valid. If that is the case, and if such 2993 * operations should be retried, then no exception will be thrown. Otherwise, 2994 * an appropriate {@code LDAPException} will be thrown. 2995 * 2996 * @param t The {@code Throwable} object that was caught. 2997 * @param o The type of operation for which to make the determination. 2998 * @param conn The connection to be released to the pool. 2999 * 3000 * @throws LDAPException To indicate that a problem occurred during LDAP 3001 * processing and the operation should not be retried. 3002 */ 3003 private void throwLDAPExceptionIfShouldNotRetry(@NotNull final Throwable t, 3004 @NotNull final OperationType o, 3005 @NotNull final LDAPConnection conn) 3006 throws LDAPException 3007 { 3008 if ((t instanceof LDAPException) && 3009 getOperationTypesToRetryDueToInvalidConnections().contains(o)) 3010 { 3011 final LDAPException le = (LDAPException) t; 3012 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 3013 3014 try 3015 { 3016 healthCheck.ensureConnectionValidAfterException(conn, le); 3017 } 3018 catch (final Exception e) 3019 { 3020 // If we have gotten this exception, then it indicates that the 3021 // connection is no longer valid and the operation should be retried. 3022 Debug.debugException(e); 3023 return; 3024 } 3025 } 3026 3027 throwLDAPException(t, conn); 3028 } 3029 3030 3031 3032 /** 3033 * Examines the provided {@code Throwable} object to determine whether it 3034 * represents an {@code LDAPException} that indicates the associated 3035 * connection may no longer be valid. If that is the case, and if such 3036 * operations should be retried, then no exception will be thrown. Otherwise, 3037 * an appropriate {@code LDAPSearchException} will be thrown. 3038 * 3039 * @param t The {@code Throwable} object that was caught. 3040 * @param conn The connection to be released to the pool. 3041 * 3042 * @throws LDAPSearchException To indicate that a problem occurred during 3043 * LDAP processing and the operation should not 3044 * be retried. 3045 */ 3046 private void throwLDAPSearchExceptionIfShouldNotRetry( 3047 @NotNull final Throwable t, 3048 @NotNull final LDAPConnection conn) 3049 throws LDAPSearchException 3050 { 3051 if ((t instanceof LDAPException) && 3052 getOperationTypesToRetryDueToInvalidConnections().contains( 3053 OperationType.SEARCH)) 3054 { 3055 final LDAPException le = (LDAPException) t; 3056 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 3057 3058 try 3059 { 3060 healthCheck.ensureConnectionValidAfterException(conn, le); 3061 } 3062 catch (final Exception e) 3063 { 3064 // If we have gotten this exception, then it indicates that the 3065 // connection is no longer valid and the operation should be retried. 3066 Debug.debugException(e); 3067 return; 3068 } 3069 } 3070 3071 throwLDAPSearchException(t, conn); 3072 } 3073 3074 3075 3076 /** 3077 * Handles the provided {@code Throwable} object by ensuring that the provided 3078 * connection is released to the pool and throwing an appropriate 3079 * {@code LDAPException} object. 3080 * 3081 * @param t The {@code Throwable} object that was caught. 3082 * @param conn The connection to be released to the pool. 3083 * 3084 * @throws LDAPException To indicate that a problem occurred during LDAP 3085 * processing. 3086 */ 3087 void throwLDAPException(@NotNull final Throwable t, 3088 @NotNull final LDAPConnection conn) 3089 throws LDAPException 3090 { 3091 Debug.debugException(t); 3092 if (t instanceof LDAPException) 3093 { 3094 final LDAPException le = (LDAPException) t; 3095 releaseConnectionAfterException(conn, le); 3096 throw le; 3097 } 3098 else 3099 { 3100 releaseDefunctConnection(conn); 3101 StaticUtils.rethrowIfError(t); 3102 throw new LDAPException(ResultCode.LOCAL_ERROR, 3103 ERR_POOL_OP_EXCEPTION.get(StaticUtils.getExceptionMessage(t)), t); 3104 } 3105 } 3106 3107 3108 3109 /** 3110 * Handles the provided {@code Throwable} object by ensuring that the provided 3111 * connection is released to the pool and throwing an appropriate 3112 * {@code LDAPSearchException} object. 3113 * 3114 * @param t The {@code Throwable} object that was caught. 3115 * @param conn The connection to be released to the pool. 3116 * 3117 * @throws LDAPSearchException To indicate that a problem occurred during 3118 * LDAP search processing. 3119 */ 3120 void throwLDAPSearchException(@NotNull final Throwable t, 3121 @NotNull final LDAPConnection conn) 3122 throws LDAPSearchException 3123 { 3124 Debug.debugException(t); 3125 if (t instanceof LDAPException) 3126 { 3127 final LDAPSearchException lse; 3128 if (t instanceof LDAPSearchException) 3129 { 3130 lse = (LDAPSearchException) t; 3131 } 3132 else 3133 { 3134 lse = new LDAPSearchException((LDAPException) t); 3135 } 3136 3137 releaseConnectionAfterException(conn, lse); 3138 throw lse; 3139 } 3140 else 3141 { 3142 releaseDefunctConnection(conn); 3143 StaticUtils.rethrowIfError(t); 3144 throw new LDAPSearchException(ResultCode.LOCAL_ERROR, 3145 ERR_POOL_OP_EXCEPTION.get(StaticUtils.getExceptionMessage(t)), t); 3146 } 3147 } 3148 3149 3150 3151 /** 3152 * Retrieves a string representation of this connection pool. 3153 * 3154 * @return A string representation of this connection pool. 3155 */ 3156 @Override() 3157 @NotNull() 3158 public final String toString() 3159 { 3160 final StringBuilder buffer = new StringBuilder(); 3161 toString(buffer); 3162 return buffer.toString(); 3163 } 3164 3165 3166 3167 /** 3168 * Appends a string representation of this connection pool to the provided 3169 * buffer. 3170 * 3171 * @param buffer The buffer to which the string representation should be 3172 * appended. 3173 */ 3174 public abstract void toString(@NotNull StringBuilder buffer); 3175}