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.Serializable; 041import java.util.concurrent.atomic.AtomicLong; 042 043import com.unboundid.util.Mutable; 044import com.unboundid.util.ThreadSafety; 045import com.unboundid.util.ThreadSafetyLevel; 046 047 048 049/** 050 * This class provides a data structure with information about usage of an LDAP 051 * connection pool. Calls to update statistics maintained by this class are 052 * threadsafe, but attempts to access different statistics may not be consistent 053 * if operations may be in progress in the connection pool. 054 * <BR><BR> 055 * The set of statistics maintained for connection pools include: 056 * <UL> 057 * <LI>The current number of connections that are available within the 058 * pool.</LI> 059 * <LI>The maximum number of connections that may be available within the 060 * pool.</LI> 061 * <LI>The total number of connections that have been successfully checked out 062 * of the pool.</LI> 063 * <LI>The number of connections that have been successfully checked out of 064 * of the pool without needing to wait for a connection to become 065 * available. 066 * <LI>The number of connections that have been successfully checked out of 067 * the pool after waiting for a connection to become available.</LI> 068 * <LI>The number of connections that have been successfully checked out of 069 * the pool after creating a new connection to service the request.</LI> 070 * <LI>The number of failed attempts to check a connection out of the 071 * pool.</LI> 072 * <LI>The number of connections that have been released back to the pool as 073 * valid.</LI> 074 * <LI>The number of connections that have been closed as defunct.</LI> 075 * <LI>The number of connections that have been closed as expired (i.e., that 076 * had been established for the maximum connection age).</LI> 077 * <LI>The number of connections that have been closed as unneeded (because 078 * the pool already had the maximum number of available connections).</LI> 079 * <LI>The number of successful attempts to create a new connection for use in 080 * the pool.</LI> 081 * <LI>The number of failed attempts to create a new connection for use in the 082 * pool.</LI> 083 * </UL> 084 */ 085@Mutable() 086@ThreadSafety(level=ThreadSafetyLevel.MOSTLY_THREADSAFE) 087public final class LDAPConnectionPoolStatistics 088 implements Serializable 089{ 090 /** 091 * The serial version UID for this serializable class. 092 */ 093 private static final long serialVersionUID = 1493039391352814874L; 094 095 096 097 // The number of connections that have been closed as defunct. 098 private final AtomicLong numConnectionsClosedDefunct; 099 100 // The number of connections that have been closed because they were expired. 101 private final AtomicLong numConnectionsClosedExpired; 102 103 // The number of connections that have been closed because they were no longer 104 // needed. 105 private final AtomicLong numConnectionsClosedUnneeded; 106 107 // The number of failed attempts to check out a connection from the pool. 108 private final AtomicLong numFailedCheckouts; 109 110 // The number of failed attempts to create a connection for use in the pool. 111 private final AtomicLong numFailedConnectionAttempts; 112 113 // The number of valid connections released back to the pool. 114 private final AtomicLong numReleasedValid; 115 116 // The number of successful attempts to check out a connection from the pool. 117 private final AtomicLong numSuccessfulCheckouts; 118 119 // The number of successful checkout attempts that retrieved a connection from 120 // the pool after waiting for it to become available. 121 private final AtomicLong numSuccessfulCheckoutsAfterWait; 122 123 // The number of successful checkout attempts that had to create a new 124 // connection because none were available. 125 private final AtomicLong numSuccessfulCheckoutsNewConnection; 126 127 // The number of successful checkout attempts that were able to take an 128 // existing connection without waiting. 129 private final AtomicLong numSuccessfulCheckoutsWithoutWait; 130 131 // The number successful attempts to create a connection for use in the pool. 132 private final AtomicLong numSuccessfulConnectionAttempts; 133 134 // The connection pool with which these statistics are associated. 135 private final AbstractConnectionPool pool; 136 137 138 139 /** 140 * Creates a new instance of this LDAP connection pool statistics object. All 141 * of the counts will be initialized to zero. 142 * 143 * @param pool The connection pool with which these statistics are 144 * associated. 145 */ 146 public LDAPConnectionPoolStatistics(final AbstractConnectionPool pool) 147 { 148 this.pool = pool; 149 150 numSuccessfulConnectionAttempts = new AtomicLong(0L); 151 numFailedConnectionAttempts = new AtomicLong(0L); 152 numConnectionsClosedDefunct = new AtomicLong(0L); 153 numConnectionsClosedExpired = new AtomicLong(0L); 154 numConnectionsClosedUnneeded = new AtomicLong(0L); 155 numSuccessfulCheckouts = new AtomicLong(0L); 156 numSuccessfulCheckoutsAfterWait = new AtomicLong(0L); 157 numSuccessfulCheckoutsNewConnection = new AtomicLong(0L); 158 numSuccessfulCheckoutsWithoutWait = new AtomicLong(0L); 159 numFailedCheckouts = new AtomicLong(0L); 160 numReleasedValid = new AtomicLong(0L); 161 } 162 163 164 165 /** 166 * Resets all counters back to zero. 167 */ 168 public void reset() 169 { 170 numSuccessfulConnectionAttempts.set(0L); 171 numFailedConnectionAttempts.set(0L); 172 numConnectionsClosedDefunct.set(0L); 173 numConnectionsClosedExpired.set(0L); 174 numConnectionsClosedUnneeded.set(0L); 175 numSuccessfulCheckouts.set(0L); 176 numSuccessfulCheckoutsAfterWait.set(0L); 177 numSuccessfulCheckoutsNewConnection.set(0L); 178 numSuccessfulCheckoutsWithoutWait.set(0L); 179 numFailedCheckouts.set(0L); 180 numReleasedValid.set(0L); 181 } 182 183 184 185 /** 186 * Retrieves the number of connections that have been successfully created for 187 * use in conjunction with the connection pool. 188 * 189 * @return The number of connections that have been created for use in 190 * conjunction with the connection pool. 191 */ 192 public long getNumSuccessfulConnectionAttempts() 193 { 194 return numSuccessfulConnectionAttempts.get(); 195 } 196 197 198 199 /** 200 * Increments the number of connections that have been successfully created 201 * for use in conjunction with the connection pool. 202 */ 203 void incrementNumSuccessfulConnectionAttempts() 204 { 205 numSuccessfulConnectionAttempts.incrementAndGet(); 206 } 207 208 209 210 /** 211 * Retrieves the number of failed attempts to create a connection for use in 212 * the connection pool. 213 * 214 * @return The number of failed attempts to create a connection for use in 215 * the connection pool. 216 */ 217 public long getNumFailedConnectionAttempts() 218 { 219 return numFailedConnectionAttempts.get(); 220 } 221 222 223 224 /** 225 * Increments the number of failed attempts to create a connection for use in 226 * the connection pool. 227 */ 228 void incrementNumFailedConnectionAttempts() 229 { 230 numFailedConnectionAttempts.incrementAndGet(); 231 } 232 233 234 235 /** 236 * Retrieves the number of connections that have been closed as defunct (i.e., 237 * they are no longer believed to be valid). 238 * 239 * @return The number of connections that have been closed as defunct. 240 */ 241 public long getNumConnectionsClosedDefunct() 242 { 243 return numConnectionsClosedDefunct.get(); 244 } 245 246 247 248 /** 249 * Increments the number of connections that have been closed as defunct. 250 */ 251 void incrementNumConnectionsClosedDefunct() 252 { 253 numConnectionsClosedDefunct.incrementAndGet(); 254 } 255 256 257 258 /** 259 * Retrieves the number of connections that have been closed as expired (i.e., 260 * they have been established for longer than the maximum connection age for 261 * the pool). 262 * 263 * @return The number of connections that have been closed as expired. 264 */ 265 public long getNumConnectionsClosedExpired() 266 { 267 return numConnectionsClosedExpired.get(); 268 } 269 270 271 272 /** 273 * Increments the number of connections that have been closed as expired. 274 */ 275 void incrementNumConnectionsClosedExpired() 276 { 277 numConnectionsClosedExpired.incrementAndGet(); 278 } 279 280 281 282 /** 283 * Retrieves the number of connections that have been closed as unneeded 284 * (i.e., they were created in response to heavy load but are no longer needed 285 * to meet the current load, or they were closed when the pool was closed). 286 * 287 * @return The number of connections that have been closed as unneeded. 288 */ 289 public long getNumConnectionsClosedUnneeded() 290 { 291 return numConnectionsClosedUnneeded.get(); 292 } 293 294 295 296 /** 297 * Increments the number of connections that have been closed as unneeded. 298 */ 299 void incrementNumConnectionsClosedUnneeded() 300 { 301 numConnectionsClosedUnneeded.incrementAndGet(); 302 } 303 304 305 306 /** 307 * Retrieves the number of successful attempts to check out a connection from 308 * the pool (including connections checked out for internal use by operations 309 * processed as part of the pool). 310 * 311 * @return The number of successful attempts to check out a connection from 312 * the pool. 313 */ 314 public long getNumSuccessfulCheckouts() 315 { 316 return numSuccessfulCheckouts.get(); 317 } 318 319 320 321 /** 322 * Retrieves the number of successful attempts to check out a connection from 323 * the pool that were able to obtain an existing connection without waiting. 324 * 325 * @return The number of successful attempts to check out a connection from 326 * the pool that were able to obtain an existing connection without 327 * waiting. 328 */ 329 public long getNumSuccessfulCheckoutsWithoutWaiting() 330 { 331 return numSuccessfulCheckoutsWithoutWait.get(); 332 } 333 334 335 336 /** 337 * Retrieves the number of successful attempts to check out a connection from 338 * the pool that had to wait for a connection to become available. 339 * 340 * @return The number of successful attempts to check out a connection from 341 * the pool that had to wait for a connection to become available. 342 */ 343 public long getNumSuccessfulCheckoutsAfterWaiting() 344 { 345 return numSuccessfulCheckoutsAfterWait.get(); 346 } 347 348 349 350 /** 351 * Retrieves the number of successful attempts to check out a connection from 352 * the pool that had to create a new connection because no existing 353 * connections were available. 354 * 355 * @return The number of successful attempts to check out a connection from 356 * the pool that had to create a new connection because no existing 357 * connections were available. 358 */ 359 public long getNumSuccessfulCheckoutsNewConnection() 360 { 361 return numSuccessfulCheckoutsNewConnection.get(); 362 } 363 364 365 366 /** 367 * Increments the number of successful attempts to check out a connection from 368 * the pool without waiting. 369 */ 370 void incrementNumSuccessfulCheckoutsWithoutWaiting() 371 { 372 numSuccessfulCheckouts.incrementAndGet(); 373 numSuccessfulCheckoutsWithoutWait.incrementAndGet(); 374 } 375 376 377 378 /** 379 * Increments the number of successful attempts to check out a connection from 380 * the pool after waiting. 381 */ 382 void incrementNumSuccessfulCheckoutsAfterWaiting() 383 { 384 numSuccessfulCheckouts.incrementAndGet(); 385 numSuccessfulCheckoutsAfterWait.incrementAndGet(); 386 } 387 388 389 390 /** 391 * Increments the number of successful attempts to check out a connection from 392 * the pool after creating a new connection. 393 */ 394 void incrementNumSuccessfulCheckoutsNewConnection() 395 { 396 numSuccessfulCheckouts.incrementAndGet(); 397 numSuccessfulCheckoutsNewConnection.incrementAndGet(); 398 } 399 400 401 402 /** 403 * Retrieves the number of failed attempts to check out a connection from 404 * the pool (including connections checked out for internal use by operations 405 * processed as part of the pool). 406 * 407 * @return The number of failed attempts to check out a connection from 408 * the pool. 409 */ 410 public long getNumFailedCheckouts() 411 { 412 return numFailedCheckouts.get(); 413 } 414 415 416 417 /** 418 * Increments the number of failed attempts to check out a connection from 419 * the pool. 420 */ 421 void incrementNumFailedCheckouts() 422 { 423 numFailedCheckouts.incrementAndGet(); 424 } 425 426 427 428 /** 429 * Retrieves the number of times a valid, usable connection has been released 430 * back to the pool after being checked out (including connections checked out 431 * for internal use by operations processed within the pool). 432 * 433 * @return The number of times a valid connection has been released back to 434 * the pool. 435 */ 436 public long getNumReleasedValid() 437 { 438 return numReleasedValid.get(); 439 } 440 441 442 443 /** 444 * Increments the number of times a valid, usable connection has been released 445 * back to the pool. 446 */ 447 void incrementNumReleasedValid() 448 { 449 numReleasedValid.incrementAndGet(); 450 } 451 452 453 454 /** 455 * Retrieves the number of connections currently available for use in the 456 * pool, if that information is available. 457 * 458 * @return The number of connections currently available for use in the pool, 459 * or -1 if that is not applicable for the associated connection pool 460 * implementation. 461 */ 462 public int getNumAvailableConnections() 463 { 464 return pool.getCurrentAvailableConnections(); 465 } 466 467 468 469 /** 470 * Retrieves the maximum number of connections that may be available in the 471 * pool at any time, if that information is available. 472 * 473 * @return The maximum number of connections that may be available in the 474 * pool at any time, or -1 if that is not applicable for the 475 * associated connection pool implementation. 476 */ 477 public int getMaximumAvailableConnections() 478 { 479 return pool.getMaximumAvailableConnections(); 480 } 481 482 483 484 /** 485 * Retrieves a string representation of this LDAP connection pool statistics 486 * object. 487 * 488 * @return A string representation of this LDAP connection pool statistics 489 * object. 490 */ 491 @Override() 492 public String toString() 493 { 494 final StringBuilder buffer = new StringBuilder(); 495 toString(buffer); 496 return buffer.toString(); 497 } 498 499 500 501 /** 502 * Appends a string representation of this LDAP connection pool statistics 503 * object to the provided buffer. 504 * 505 * @param buffer The buffer to which the string representation should be 506 * appended. 507 */ 508 public void toString(final StringBuilder buffer) 509 { 510 final long availableConns = pool.getCurrentAvailableConnections(); 511 final long maxConns = pool.getMaximumAvailableConnections(); 512 final long successfulConns = numSuccessfulConnectionAttempts.get(); 513 final long failedConns = numFailedConnectionAttempts.get(); 514 final long connsClosedDefunct = numConnectionsClosedDefunct.get(); 515 final long connsClosedExpired = numConnectionsClosedExpired.get(); 516 final long connsClosedUnneeded = numConnectionsClosedUnneeded.get(); 517 final long successfulCheckouts = numSuccessfulCheckouts.get(); 518 final long failedCheckouts = numFailedCheckouts.get(); 519 final long releasedValid = numReleasedValid.get(); 520 521 buffer.append("LDAPConnectionPoolStatistics(numAvailableConnections="); 522 buffer.append(availableConns); 523 buffer.append(", maxAvailableConnections="); 524 buffer.append(maxConns); 525 buffer.append(", numSuccessfulConnectionAttempts="); 526 buffer.append(successfulConns); 527 buffer.append(", numFailedConnectionAttempts="); 528 buffer.append(failedConns); 529 buffer.append(", numConnectionsClosedDefunct="); 530 buffer.append(connsClosedDefunct); 531 buffer.append(", numConnectionsClosedExpired="); 532 buffer.append(connsClosedExpired); 533 buffer.append(", numConnectionsClosedUnneeded="); 534 buffer.append(connsClosedUnneeded); 535 buffer.append(", numSuccessfulCheckouts="); 536 buffer.append(successfulCheckouts); 537 buffer.append(", numFailedCheckouts="); 538 buffer.append(failedCheckouts); 539 buffer.append(", numReleasedValid="); 540 buffer.append(releasedValid); 541 buffer.append(')'); 542 } 543}