001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2011-2015 ForgeRock AS 026 */ 027 028package org.forgerock.opendj.ldap; 029 030import static org.forgerock.opendj.ldap.RequestHandlerFactoryAdapter.adaptRequestHandler; 031 032import java.net.InetAddress; 033import java.net.InetSocketAddress; 034import java.util.concurrent.ScheduledExecutorService; 035import java.util.concurrent.TimeUnit; 036 037import org.forgerock.opendj.ldap.requests.BindRequest; 038import org.forgerock.opendj.ldap.requests.SearchRequest; 039import org.forgerock.util.Reject; 040import org.forgerock.util.promise.Promise; 041 042/** 043 * This class contains methods for creating and manipulating connection 044 * factories and connections. 045 */ 046public final class Connections { 047 /** 048 * Creates a new authenticated connection factory which will obtain 049 * connections using the provided connection factory and immediately perform 050 * the provided Bind request. 051 * <p> 052 * The connections returned by an authenticated connection factory support 053 * all operations with the exception of Bind requests. Attempts to perform a 054 * Bind will result in an {@code UnsupportedOperationException}. 055 * <p> 056 * If the Bind request fails for some reason (e.g. invalid credentials), 057 * then the connection attempt will fail and an {@link LdapException} 058 * will be thrown. 059 * 060 * @param factory 061 * The connection factory to use for connecting to the Directory 062 * Server. 063 * @param request 064 * The Bind request to use for authentication. 065 * @return The new connection pool. 066 * @throws NullPointerException 067 * If {@code factory} or {@code request} was {@code null}. 068 */ 069 public static ConnectionFactory newAuthenticatedConnectionFactory( 070 final ConnectionFactory factory, final BindRequest request) { 071 Reject.ifNull(factory, request); 072 073 return new AuthenticatedConnectionFactory(factory, request); 074 } 075 076 /** 077 * Creates a new connection pool which creates new connections as needed 078 * using the provided connection factory, but will reuse previously 079 * allocated connections when they are available. 080 * <p> 081 * Connections which have not been used for sixty seconds are closed and 082 * removed from the pool. Thus, a pool that remains idle for long enough 083 * will not contain any cached connections. 084 * <p> 085 * Connections obtained from the connection pool are guaranteed to be valid 086 * immediately before being returned to the calling application. More 087 * specifically, connections which have remained idle in the connection pool 088 * for a long time and which have been remotely closed due to a time out 089 * will never be returned. However, once a pooled connection has been 090 * obtained it is the responsibility of the calling application to handle 091 * subsequent connection failures, these being signaled via a 092 * {@link ConnectionException}. 093 * 094 * @param factory 095 * The connection factory to use for creating new connections. 096 * @return The new connection pool. 097 * @throws NullPointerException 098 * If {@code factory} was {@code null}. 099 */ 100 public static ConnectionPool newCachedConnectionPool(final ConnectionFactory factory) { 101 return new CachedConnectionPool(factory, 0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, null); 102 } 103 104 /** 105 * Creates a new connection pool which creates new connections as needed 106 * using the provided connection factory, but will reuse previously 107 * allocated connections when they are available. 108 * <p> 109 * Attempts to use more than {@code maximumPoolSize} connections at once 110 * will block until a connection is released back to the pool. In other 111 * words, this pool will prevent applications from using more than 112 * {@code maximumPoolSize} connections at the same time. 113 * <p> 114 * Connections which have not been used for the provided {@code idleTimeout} 115 * period are closed and removed from the pool, until there are only 116 * {@code corePoolSize} connections remaining. 117 * <p> 118 * Connections obtained from the connection pool are guaranteed to be valid 119 * immediately before being returned to the calling application. More 120 * specifically, connections which have remained idle in the connection pool 121 * for a long time and which have been remotely closed due to a time out 122 * will never be returned. However, once a pooled connection has been 123 * obtained it is the responsibility of the calling application to handle 124 * subsequent connection failures, these being signaled via a 125 * {@link ConnectionException}. 126 * 127 * @param factory 128 * The connection factory to use for creating new connections. 129 * @param corePoolSize 130 * The minimum number of connections to keep in the pool, even if 131 * they are idle. 132 * @param maximumPoolSize 133 * The maximum number of connections to allow in the pool. 134 * @param idleTimeout 135 * The time out period, after which unused non-core connections 136 * will be closed. 137 * @param unit 138 * The time unit for the {@code keepAliveTime} argument. 139 * @return The new connection pool. 140 * @throws IllegalArgumentException 141 * If {@code corePoolSize}, {@code maximumPoolSize} are less 142 * than or equal to zero, or if {@code idleTimeout} is negative, 143 * or if {@code corePoolSize} is greater than 144 * {@code maximumPoolSize}, or if {@code idleTimeout} is 145 * non-zero and {@code unit} is {@code null}. 146 * @throws NullPointerException 147 * If {@code factory} was {@code null}. 148 */ 149 public static ConnectionPool newCachedConnectionPool(final ConnectionFactory factory, 150 final int corePoolSize, final int maximumPoolSize, final long idleTimeout, 151 final TimeUnit unit) { 152 return new CachedConnectionPool(factory, corePoolSize, maximumPoolSize, idleTimeout, unit, 153 null); 154 } 155 156 /** 157 * Creates a new connection pool which creates new connections as needed 158 * using the provided connection factory, but will reuse previously 159 * allocated connections when they are available. 160 * <p> 161 * Attempts to use more than {@code maximumPoolSize} connections at once 162 * will block until a connection is released back to the pool. In other 163 * words, this pool will prevent applications from using more than 164 * {@code maximumPoolSize} connections at the same time. 165 * <p> 166 * Connections which have not been used for the provided {@code idleTimeout} 167 * period are closed and removed from the pool, until there are only 168 * {@code corePoolSize} connections remaining. 169 * <p> 170 * Connections obtained from the connection pool are guaranteed to be valid 171 * immediately before being returned to the calling application. More 172 * specifically, connections which have remained idle in the connection pool 173 * for a long time and which have been remotely closed due to a time out 174 * will never be returned. However, once a pooled connection has been 175 * obtained it is the responsibility of the calling application to handle 176 * subsequent connection failures, these being signaled via a 177 * {@link ConnectionException}. 178 * 179 * @param factory 180 * The connection factory to use for creating new connections. 181 * @param corePoolSize 182 * The minimum number of connections to keep in the pool, even if 183 * they are idle. 184 * @param maximumPoolSize 185 * The maximum number of connections to allow in the pool. 186 * @param idleTimeout 187 * The time out period, after which unused non-core connections 188 * will be closed. 189 * @param unit 190 * The time unit for the {@code keepAliveTime} argument. 191 * @param scheduler 192 * The scheduler which should be used for periodically checking 193 * for idle connections, or {@code null} if the default scheduler 194 * should be used. 195 * @return The new connection pool. 196 * @throws IllegalArgumentException 197 * If {@code corePoolSize}, {@code maximumPoolSize} are less 198 * than or equal to zero, or if {@code idleTimeout} is negative, 199 * or if {@code corePoolSize} is greater than 200 * {@code maximumPoolSize}, or if {@code idleTimeout} is 201 * non-zero and {@code unit} is {@code null}. 202 * @throws NullPointerException 203 * If {@code factory} was {@code null}. 204 */ 205 public static ConnectionPool newCachedConnectionPool(final ConnectionFactory factory, 206 final int corePoolSize, final int maximumPoolSize, final long idleTimeout, 207 final TimeUnit unit, final ScheduledExecutorService scheduler) { 208 return new CachedConnectionPool(factory, corePoolSize, maximumPoolSize, idleTimeout, unit, 209 scheduler); 210 } 211 212 /** 213 * Creates a new connection pool which will maintain {@code poolSize} 214 * connections created using the provided connection factory. 215 * <p> 216 * Attempts to use more than {@code poolSize} connections at once will block 217 * until a connection is released back to the pool. In other words, this 218 * pool will prevent applications from using more than {@code poolSize} 219 * connections at the same time. 220 * <p> 221 * Connections obtained from the connection pool are guaranteed to be valid 222 * immediately before being returned to the calling application. More 223 * specifically, connections which have remained idle in the connection pool 224 * for a long time and which have been remotely closed due to a time out 225 * will never be returned. However, once a pooled connection has been 226 * obtained it is the responsibility of the calling application to handle 227 * subsequent connection failures, these being signaled via a 228 * {@link ConnectionException}. 229 * 230 * @param factory 231 * The connection factory to use for creating new connections. 232 * @param poolSize 233 * The maximum size of the connection pool. 234 * @return The new connection pool. 235 * @throws IllegalArgumentException 236 * If {@code poolSize} is negative. 237 * @throws NullPointerException 238 * If {@code factory} was {@code null}. 239 */ 240 public static ConnectionPool newFixedConnectionPool(final ConnectionFactory factory, 241 final int poolSize) { 242 return new CachedConnectionPool(factory, poolSize, poolSize, 0L, null, null); 243 } 244 245 /** 246 * Creates a new heart-beat connection factory which will create connections 247 * using the provided connection factory and periodically ping any created 248 * connections in order to detect that they are still alive every 10 seconds 249 * using the default scheduler. Connections will be marked as having failed 250 * if a heart-beat takes longer than 3 seconds. 251 * 252 * @param factory 253 * The connection factory to use for creating connections. 254 * @return The new heart-beat connection factory. 255 * @throws NullPointerException 256 * If {@code factory} was {@code null}. 257 */ 258 public static ConnectionFactory newHeartBeatConnectionFactory(final ConnectionFactory factory) { 259 return new HeartBeatConnectionFactory(factory, 10, 3, TimeUnit.SECONDS, null, null); 260 } 261 262 /** 263 * Creates a new heart-beat connection factory which will create connections 264 * using the provided connection factory and periodically ping any created 265 * connections in order to detect that they are still alive using the 266 * specified frequency and the default scheduler. 267 * 268 * @param factory 269 * The connection factory to use for creating connections. 270 * @param interval 271 * The interval between keepalive pings. 272 * @param timeout 273 * The heart-beat timeout after which a connection will be marked 274 * as failed. 275 * @param unit 276 * The time unit for the interval between keepalive pings. 277 * @return The new heart-beat connection factory. 278 * @throws IllegalArgumentException 279 * If {@code interval} was negative. 280 * @throws NullPointerException 281 * If {@code factory} or {@code unit} was {@code null}. 282 */ 283 public static ConnectionFactory newHeartBeatConnectionFactory(final ConnectionFactory factory, 284 final long interval, final long timeout, final TimeUnit unit) { 285 return new HeartBeatConnectionFactory(factory, interval, timeout, unit, null, null); 286 } 287 288 /** 289 * Creates a new heart-beat connection factory which will create connections 290 * using the provided connection factory and periodically ping any created 291 * connections using the specified search request in order to detect that 292 * they are still alive. 293 * 294 * @param factory 295 * The connection factory to use for creating connections. 296 * @param interval 297 * The interval between keepalive pings. 298 * @param timeout 299 * The heart-beat timeout after which a connection will be marked 300 * as failed. 301 * @param unit 302 * The time unit for the interval between keepalive pings. 303 * @param heartBeat 304 * The search request to use for keepalive pings. 305 * @return The new heart-beat connection factory. 306 * @throws IllegalArgumentException 307 * If {@code interval} was negative. 308 * @throws NullPointerException 309 * If {@code factory}, {@code unit}, or {@code heartBeat} was 310 * {@code null}. 311 */ 312 public static ConnectionFactory newHeartBeatConnectionFactory(final ConnectionFactory factory, 313 final long interval, final long timeout, final TimeUnit unit, 314 final SearchRequest heartBeat) { 315 return new HeartBeatConnectionFactory(factory, interval, timeout, unit, heartBeat, null); 316 } 317 318 /** 319 * Creates a new heart-beat connection factory which will create connections 320 * using the provided connection factory and periodically ping any created 321 * connections using the specified search request in order to detect that 322 * they are still alive. 323 * 324 * @param factory 325 * The connection factory to use for creating connections. 326 * @param interval 327 * The interval between keepalive pings. 328 * @param timeout 329 * The heart-beat timeout after which a connection will be marked 330 * as failed. 331 * @param unit 332 * The time unit for the interval between keepalive pings. 333 * @param heartBeat 334 * The search request to use for keepalive pings. 335 * @param scheduler 336 * The scheduler which should for periodically sending keepalive 337 * pings. 338 * @return The new heart-beat connection factory. 339 * @throws IllegalArgumentException 340 * If {@code interval} was negative. 341 * @throws NullPointerException 342 * If {@code factory}, {@code unit}, or {@code heartBeat} was 343 * {@code null}. 344 */ 345 public static ConnectionFactory newHeartBeatConnectionFactory(final ConnectionFactory factory, 346 final long interval, final long timeout, final TimeUnit unit, 347 final SearchRequest heartBeat, final ScheduledExecutorService scheduler) { 348 return new HeartBeatConnectionFactory(factory, interval, timeout, unit, heartBeat, 349 scheduler); 350 } 351 352 /** 353 * Creates a new internal client connection which will route requests to the 354 * provided {@code RequestHandler}. 355 * <p> 356 * When processing requests, {@code RequestHandler} implementations are 357 * passed a {@code RequestContext} having a pseudo {@code requestID} which 358 * is incremented for each successive internal request on a per client 359 * connection basis. The request ID may be useful for logging purposes. 360 * <p> 361 * An internal connection does not require {@code RequestHandler} 362 * implementations to return a result when processing requests. However, it 363 * is recommended that implementations do always return results even for 364 * abandoned requests. This is because application client threads may block 365 * indefinitely waiting for results. 366 * 367 * @param requestHandler 368 * The request handler which will be used for all client 369 * connections. 370 * @return The new internal connection. 371 * @throws NullPointerException 372 * If {@code requestHandler} was {@code null}. 373 */ 374 public static Connection newInternalConnection( 375 final RequestHandler<RequestContext> requestHandler) { 376 Reject.ifNull(requestHandler); 377 return newInternalConnection(adaptRequestHandler(requestHandler)); 378 } 379 380 /** 381 * Creates a new internal client connection which will route requests to the 382 * provided {@code ServerConnection}. 383 * <p> 384 * When processing requests, {@code ServerConnection} implementations are 385 * passed an integer as the first parameter. This integer represents a 386 * pseudo {@code requestID} which is incremented for each successive 387 * internal request on a per client connection basis. The request ID may be 388 * useful for logging purposes. 389 * <p> 390 * An internal connection does not require {@code ServerConnection} 391 * implementations to return a result when processing requests. However, it 392 * is recommended that implementations do always return results even for 393 * abandoned requests. This is because application client threads may block 394 * indefinitely waiting for results. 395 * 396 * @param serverConnection 397 * The server connection. 398 * @return The new internal connection. 399 * @throws NullPointerException 400 * If {@code serverConnection} was {@code null}. 401 */ 402 public static Connection newInternalConnection(final ServerConnection<Integer> serverConnection) { 403 Reject.ifNull(serverConnection); 404 return new InternalConnection(serverConnection); 405 } 406 407 /** 408 * Creates a new connection factory which binds internal client connections 409 * to the provided {@link RequestHandler}s. 410 * <p> 411 * When processing requests, {@code RequestHandler} implementations are 412 * passed an integer as the first parameter. This integer represents a 413 * pseudo {@code requestID} which is incremented for each successive 414 * internal request on a per client connection basis. The request ID may be 415 * useful for logging purposes. 416 * <p> 417 * An internal connection factory does not require {@code RequestHandler} 418 * implementations to return a result when processing requests. However, it 419 * is recommended that implementations do always return results even for 420 * abandoned requests. This is because application client threads may block 421 * indefinitely waiting for results. 422 * 423 * @param requestHandler 424 * The request handler which will be used for all client 425 * connections. 426 * @return The new internal connection factory. 427 * @throws NullPointerException 428 * If {@code requestHandler} was {@code null}. 429 */ 430 public static ConnectionFactory newInternalConnectionFactory( 431 final RequestHandler<RequestContext> requestHandler) { 432 Reject.ifNull(requestHandler); 433 return new InternalConnectionFactory<>( 434 Connections.<Void> newServerConnectionFactory(requestHandler), null); 435 } 436 437 /** 438 * Creates a new connection factory which binds internal client connections 439 * to {@link RequestHandler}s created using the provided 440 * {@link RequestHandlerFactory}. 441 * <p> 442 * When processing requests, {@code RequestHandler} implementations are 443 * passed an integer as the first parameter. This integer represents a 444 * pseudo {@code requestID} which is incremented for each successive 445 * internal request on a per client connection basis. The request ID may be 446 * useful for logging purposes. 447 * <p> 448 * An internal connection factory does not require {@code RequestHandler} 449 * implementations to return a result when processing requests. However, it 450 * is recommended that implementations do always return results even for 451 * abandoned requests. This is because application client threads may block 452 * indefinitely waiting for results. 453 * 454 * @param <C> 455 * The type of client context. 456 * @param factory 457 * The request handler factory to use for creating connections. 458 * @param clientContext 459 * The client context. 460 * @return The new internal connection factory. 461 * @throws NullPointerException 462 * If {@code factory} was {@code null}. 463 */ 464 public static <C> ConnectionFactory newInternalConnectionFactory( 465 final RequestHandlerFactory<C, RequestContext> factory, final C clientContext) { 466 Reject.ifNull(factory); 467 return new InternalConnectionFactory<>(newServerConnectionFactory(factory), clientContext); 468 } 469 470 /** 471 * Creates a new connection factory which binds internal client connections 472 * to {@link ServerConnection}s created using the provided 473 * {@link ServerConnectionFactory}. 474 * <p> 475 * When processing requests, {@code ServerConnection} implementations are 476 * passed an integer as the first parameter. This integer represents a 477 * pseudo {@code requestID} which is incremented for each successive 478 * internal request on a per client connection basis. The request ID may be 479 * useful for logging purposes. 480 * <p> 481 * An internal connection factory does not require {@code ServerConnection} 482 * implementations to return a result when processing requests. However, it 483 * is recommended that implementations do always return results even for 484 * abandoned requests. This is because application client threads may block 485 * indefinitely waiting for results. 486 * 487 * @param <C> 488 * The type of client context. 489 * @param factory 490 * The server connection factory to use for creating connections. 491 * @param clientContext 492 * The client context. 493 * @return The new internal connection factory. 494 * @throws NullPointerException 495 * If {@code factory} was {@code null}. 496 */ 497 public static <C> ConnectionFactory newInternalConnectionFactory( 498 final ServerConnectionFactory<C, Integer> factory, final C clientContext) { 499 Reject.ifNull(factory); 500 return new InternalConnectionFactory<>(factory, clientContext); 501 } 502 503 /** 504 * Creates a new load balancer which will obtain connections using the 505 * provided load balancing algorithm. 506 * 507 * @param algorithm 508 * The load balancing algorithm which will be used to obtain the 509 * next 510 * @return The new load balancer. 511 * @throws NullPointerException 512 * If {@code algorithm} was {@code null}. 513 */ 514 public static ConnectionFactory newLoadBalancer(final LoadBalancingAlgorithm algorithm) { 515 return new LoadBalancer(algorithm); 516 } 517 518 /** 519 * Creates a new connection factory which forwards connection requests to 520 * the provided factory, but whose {@code toString} method will always 521 * return {@code name}. 522 * <p> 523 * This method may be useful for debugging purposes in order to more easily 524 * identity connection factories. 525 * 526 * @param factory 527 * The connection factory to be named. 528 * @param name 529 * The name of the connection factory. 530 * @return The named connection factory. 531 * @throws NullPointerException 532 * If {@code factory} or {@code name} was {@code null}. 533 */ 534 public static ConnectionFactory newNamedConnectionFactory(final ConnectionFactory factory, 535 final String name) { 536 Reject.ifNull(factory, name); 537 538 return new ConnectionFactory() { 539 540 @Override 541 public void close() { 542 factory.close(); 543 } 544 545 @Override 546 public Connection getConnection() throws LdapException { 547 return factory.getConnection(); 548 } 549 550 @Override 551 public Promise<Connection, LdapException> getConnectionAsync() { 552 return factory.getConnectionAsync(); 553 } 554 555 @Override 556 public String toString() { 557 return name; 558 } 559 560 }; 561 } 562 563 /** 564 * Creates a new server connection factory using the provided 565 * {@link RequestHandler}. The returned factory will manage connection and 566 * request life-cycle, including request cancellation. 567 * <p> 568 * When processing requests, {@link RequestHandler} implementations are 569 * passed a {@link RequestContext} as the first parameter which may be used 570 * for detecting whether or not the request should be aborted due to 571 * cancellation requests or other events, such as connection failure. 572 * <p> 573 * The returned factory maintains state information which includes a table 574 * of active requests. Therefore, {@code RequestHandler} implementations are 575 * required to always return results in order to avoid potential memory 576 * leaks. 577 * 578 * @param <C> 579 * The type of client context. 580 * @param requestHandler 581 * The request handler which will be used for all client 582 * connections. 583 * @return The new server connection factory. 584 * @throws NullPointerException 585 * If {@code requestHandler} was {@code null}. 586 */ 587 public static <C> ServerConnectionFactory<C, Integer> newServerConnectionFactory( 588 final RequestHandler<RequestContext> requestHandler) { 589 Reject.ifNull(requestHandler); 590 return new RequestHandlerFactoryAdapter<>(new RequestHandlerFactory<C, RequestContext>() { 591 @Override 592 public RequestHandler<RequestContext> handleAccept(final C clientContext) { 593 return requestHandler; 594 } 595 }); 596 } 597 598 /** 599 * Creates a new server connection factory using the provided 600 * {@link RequestHandlerFactory}. The returned factory will manage 601 * connection and request life-cycle, including request cancellation. 602 * <p> 603 * When processing requests, {@link RequestHandler} implementations are 604 * passed a {@link RequestContext} as the first parameter which may be used 605 * for detecting whether or not the request should be aborted due to 606 * cancellation requests or other events, such as connection failure. 607 * <p> 608 * The returned factory maintains state information which includes a table 609 * of active requests. Therefore, {@code RequestHandler} implementations are 610 * required to always return results in order to avoid potential memory 611 * leaks. 612 * 613 * @param <C> 614 * The type of client context. 615 * @param factory 616 * The request handler factory to use for associating request 617 * handlers with client connections. 618 * @return The new server connection factory. 619 * @throws NullPointerException 620 * If {@code factory} was {@code null}. 621 */ 622 public static <C> ServerConnectionFactory<C, Integer> newServerConnectionFactory( 623 final RequestHandlerFactory<C, RequestContext> factory) { 624 Reject.ifNull(factory); 625 return new RequestHandlerFactoryAdapter<>(factory); 626 } 627 628 /** 629 * Returns an uncloseable view of the provided connection. Attempts to call 630 * {@link Connection#close()} or 631 * {@link Connection#close(org.forgerock.opendj.ldap.requests.UnbindRequest, String)} 632 * will be ignored. 633 * 634 * @param connection 635 * The connection whose {@code close} methods are to be disabled. 636 * @return An uncloseable view of the provided connection. 637 */ 638 public static Connection uncloseable(Connection connection) { 639 return new AbstractConnectionWrapper<Connection>(connection) { 640 @Override 641 public void close() { 642 // Do nothing. 643 } 644 645 @Override 646 public void close(org.forgerock.opendj.ldap.requests.UnbindRequest request, 647 String reason) { 648 // Do nothing. 649 }; 650 }; 651 } 652 653 /** 654 * Returns an uncloseable view of the provided connection factory. Attempts 655 * to call {@link ConnectionFactory#close()} will be ignored. 656 * 657 * @param factory 658 * The connection factory whose {@code close} method is to be 659 * disabled. 660 * @return An uncloseable view of the provided connection factory. 661 */ 662 public static ConnectionFactory uncloseable(final ConnectionFactory factory) { 663 return new ConnectionFactory() { 664 665 @Override 666 public Promise<Connection, LdapException> getConnectionAsync() { 667 return factory.getConnectionAsync(); 668 } 669 670 @Override 671 public Connection getConnection() throws LdapException { 672 return factory.getConnection(); 673 } 674 675 @Override 676 public void close() { 677 // Do nothing. 678 } 679 }; 680 } 681 682 /** 683 * Returns the host name associated with the provided 684 * {@code InetSocketAddress}, without performing a DNS lookup. This method 685 * attempts to provide functionality which is compatible with 686 * {@code InetSocketAddress.getHostString()} in JDK7. It can be removed once 687 * we drop support for JDK6. 688 * 689 * @param socketAddress 690 * The socket address which is expected to be an instance of 691 * {@code InetSocketAddress}. 692 * @return The host name associated with the provided {@code SocketAddress}, 693 * or {@code null} if it is unknown. 694 */ 695 public static String getHostString(final InetSocketAddress socketAddress) { 696 /* 697 * See OPENDJ-1270 for more information about slow DNS queries. 698 * 699 * We must avoid calling getHostName() in the case where it is likely to 700 * perform a blocking DNS query. Ideally we would call getHostString(), 701 * but the method was only added in JDK7. 702 */ 703 if (socketAddress.isUnresolved()) { 704 /* 705 * Usually socket addresses are resolved on creation. If the address 706 * is unresolved then there must be a user provided hostname instead 707 * and getHostName will not perform a reverse lookup. 708 */ 709 return socketAddress.getHostName(); 710 } else { 711 /* 712 * Simulate getHostString() by parsing the toString() 713 * representation. This assumes that the toString() representation 714 * is stable, which I assume it is because it is documented. 715 */ 716 final InetAddress address = socketAddress.getAddress(); 717 final String hostSlashIp = address.toString(); 718 final int slashPos = hostSlashIp.indexOf('/'); 719 if (slashPos == 0) { 720 return hostSlashIp.substring(1); 721 } else { 722 return hostSlashIp.substring(0, slashPos); 723 } 724 } 725 } 726 727 /** Prevent instantiation. */ 728 private Connections() { 729 // Do nothing. 730 } 731}