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