001 /* 002 * Copyright 2008-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2015 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk.unboundidds.monitors; 022 023 024 025 import java.util.Collections; 026 import java.util.LinkedHashMap; 027 import java.util.Map; 028 029 import com.unboundid.ldap.sdk.Entry; 030 import com.unboundid.util.NotMutable; 031 import com.unboundid.util.ThreadSafety; 032 import com.unboundid.util.ThreadSafetyLevel; 033 034 import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 035 036 037 038 /** 039 * <BLOCKQUOTE> 040 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 041 * LDAP SDK for Java. It is not available for use in applications that 042 * include only the Standard Edition of the LDAP SDK, and is not supported for 043 * use in conjunction with non-UnboundID products. 044 * </BLOCKQUOTE> 045 * This class defines a monitor entry that provides information about the state 046 * of the UnboundID work queue. This has replaced the traditional work queue as 047 * the default work queue implementation used by the UnboundID Directory Server, 048 * and the monitor information that it may make available includes: 049 * <UL> 050 * <LI>The number of requests that were rejected because the work queue was 051 * already at its maximum capacity.</LI> 052 * <LI>The number of operations currently held in the work queue waiting to be 053 * picked for processing by a worker thread.</LI> 054 * <LI>The average number of operations held in the work queue since startup 055 * as observed from periodic polling.</LI> 056 * <LI>The maximum number of operations held in the work queue at any time 057 * since startup as observed from periodic polling.</LI> 058 * </UL> 059 * The server should present at most one UnboundID work queue monitor entry. 060 * It can be retrieved using the 061 * {@link MonitorManager#getUnboundIDWorkQueueMonitorEntry} method. This entry 062 * provides specific methods for accessing information about the state of 063 * the work queue (e.g., the 064 * {@link UnboundIDWorkQueueMonitorEntry#getCurrentSize} method may be used 065 * to retrieve the number of operations currently held in the work queue). 066 * Alternately, this information may be accessed using the generic API. See the 067 * {@link MonitorManager} class documentation for an example that demonstrates 068 * the use of the generic API for accessing monitor data. 069 */ 070 @NotMutable() 071 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 072 public final class UnboundIDWorkQueueMonitorEntry 073 extends MonitorEntry 074 { 075 /** 076 * The structural object class used in LDAP statistics monitor entries. 077 */ 078 static final String UNBOUNDID_WORK_QUEUE_MONITOR_OC = 079 "ds-unboundid-work-queue-monitor-entry"; 080 081 082 083 /** 084 * The name of the attribute that contains the average worker thread percent 085 * busy. 086 */ 087 private static final String ATTR_AVERAGE_QUEUE_TIME_MILLIS = 088 "average-operation-queue-time-millis"; 089 090 091 092 /** 093 * The name of the attribute that contains the average worker thread percent 094 * busy. 095 */ 096 private static final String ATTR_AVERAGE_PCT_BUSY = 097 "average-worker-thread-percent-busy"; 098 099 100 101 /** 102 * The name of the attribute that contains the average observed work queue 103 * size. 104 */ 105 private static final String ATTR_AVERAGE_SIZE = "average-queue-size"; 106 107 108 109 /** 110 * The name of the attribute that contains the current work queue size. 111 */ 112 private static final String ATTR_CURRENT_PCT_BUSY = 113 "current-worker-thread-percent-busy"; 114 115 116 117 /** 118 * The name of the attribute that contains the current work queue size. 119 */ 120 private static final String ATTR_CURRENT_SIZE = "current-queue-size"; 121 122 123 124 /** 125 * The name of the attribute that contains the maximum observed work queue 126 * size. 127 */ 128 private static final String ATTR_MAX_SIZE = "max-queue-size"; 129 130 131 132 /** 133 * The name of the attribute that contains the maximum worker thread percent 134 * busy. 135 */ 136 private static final String ATTR_MAX_PCT_BUSY = 137 "max-worker-thread-percent-busy"; 138 139 140 141 /** 142 * The name of the attribute that contains the number of busy worker threads. 143 */ 144 private static final String ATTR_NUM_BUSY_WORKER_THREADS = 145 "num-busy-worker-threads"; 146 147 148 149 /** 150 * The name of the attribute that contains the number of worker threads. 151 */ 152 private static final String ATTR_NUM_WORKER_THREADS = "num-worker-threads"; 153 154 155 156 /** 157 * The name of the attribute that contains the average worker thread percent 158 * busy. 159 */ 160 private static final String ATTR_RECENT_AVERAGE_SIZE = 161 "recent-average-queue-size"; 162 163 164 165 /** 166 * The name of the attribute that contains the average worker thread percent 167 * busy. 168 */ 169 private static final String ATTR_RECENT_QUEUE_TIME_MILLIS = 170 "recent-operation-queue-time-millis"; 171 172 173 174 /** 175 * The name of the attribute that contains the recent worker thread percent 176 * busy. 177 */ 178 private static final String ATTR_RECENT_PCT_BUSY = 179 "recent-worker-thread-percent-busy"; 180 181 182 183 /** 184 * The name of the attribute that contains the total number of requests that 185 * have been rejected because the work queue was full. 186 */ 187 private static final String ATTR_REQUESTS_REJECTED = "rejected-count"; 188 189 190 191 /** 192 * The name of the attribute that contains the current size of the work queue 193 * reserved for operations processed as part of administrative sessions. 194 */ 195 private static final String ATTR_CURRENT_ADMIN_QUEUE_SIZE = 196 "current-administrative-session-queue-size"; 197 198 199 200 /** 201 * The name of the attribute that contains the number of worker threads that 202 * are currently busy processing operations as part of an administrative 203 * session. 204 */ 205 private static final String ATTR_MAX_ADMIN_SESSION_QUEUE_SIZE = 206 "max-administrative-session-queue-size"; 207 208 209 210 /** 211 * The name of the attribute that contains the total number of worker threads 212 * reserved for processing operations that are part of an administrative 213 * session. 214 */ 215 private static final String ATTR_NUM_ADMIN_WORKER_THREADS = 216 "num-administrative-session-worker-threads"; 217 218 219 220 /** 221 * The name of the attribute that contains the number of worker threads that 222 * are currently busy processing operations as part of an administrative 223 * session. 224 */ 225 private static final String ATTR_NUM_BUSY_ADMIN_WORKER_THREADS = 226 "num-busy-administrative-session-worker-threads"; 227 228 229 230 /** 231 * The serial version UID for this serializable class. 232 */ 233 private static final long serialVersionUID = -304216058351812232L; 234 235 236 237 // The average queue time in milliseconds. 238 private final Long averageQueueTimeMillis; 239 240 // The average worker thread percent busy. 241 private final Long averagePercentBusy; 242 243 // The average work queue size. 244 private final Long averageSize; 245 246 // The current administrative session work queue size. 247 private final Long currentAdminSize; 248 249 // The current work queue size. 250 private final Long currentSize; 251 252 // The current worker thread percent busy. 253 private final Long currentPercentBusy; 254 255 // The maximum administrative session work queue size. 256 private final Long maxAdminSize; 257 258 // The maximum worker thread percent busy. 259 private final Long maxPercentBusy; 260 261 // The maximum work queue size. 262 private final Long maxSize; 263 264 // The number of administrative session worker threads. 265 private final Long numAdminWorkerThreads; 266 267 // The number of busy worker threads. 268 private final Long numBusyWorkerThreads; 269 270 // The number of busy administrative session worker threads. 271 private final Long numBusyAdminWorkerThreads; 272 273 // The number of worker threads. 274 private final Long numWorkerThreads; 275 276 // The recent average work queue size. 277 private final Long recentAverageSize; 278 279 // The recent queue time in milliseconds. 280 private final Long recentQueueTimeMillis; 281 282 // The recent worker thread percent busy. 283 private final Long recentPercentBusy; 284 285 // The total number of requests rejected due to a full work queue. 286 private final Long requestsRejected; 287 288 289 290 /** 291 * Creates a new UnboundID work queue monitor entry from the provided entry. 292 * 293 * @param entry The entry to be parsed as a traditional work queue monitor 294 * entry. It must not be {@code null}. 295 */ 296 public UnboundIDWorkQueueMonitorEntry(final Entry entry) 297 { 298 super(entry); 299 300 averageSize = getLong(ATTR_AVERAGE_SIZE); 301 currentSize = getLong(ATTR_CURRENT_SIZE); 302 recentAverageSize = getLong(ATTR_RECENT_AVERAGE_SIZE); 303 maxSize = getLong(ATTR_MAX_SIZE); 304 requestsRejected = getLong(ATTR_REQUESTS_REJECTED); 305 numBusyWorkerThreads = getLong(ATTR_NUM_BUSY_WORKER_THREADS); 306 numWorkerThreads = getLong(ATTR_NUM_WORKER_THREADS); 307 currentPercentBusy = getLong(ATTR_CURRENT_PCT_BUSY); 308 averagePercentBusy = getLong(ATTR_AVERAGE_PCT_BUSY); 309 recentPercentBusy = getLong(ATTR_RECENT_PCT_BUSY); 310 maxPercentBusy = getLong(ATTR_MAX_PCT_BUSY); 311 averageQueueTimeMillis = getLong(ATTR_AVERAGE_QUEUE_TIME_MILLIS); 312 recentQueueTimeMillis = getLong(ATTR_RECENT_QUEUE_TIME_MILLIS); 313 currentAdminSize = getLong(ATTR_CURRENT_ADMIN_QUEUE_SIZE); 314 maxAdminSize = getLong(ATTR_MAX_ADMIN_SESSION_QUEUE_SIZE); 315 numAdminWorkerThreads = getLong(ATTR_NUM_ADMIN_WORKER_THREADS); 316 numBusyAdminWorkerThreads = getLong(ATTR_NUM_BUSY_ADMIN_WORKER_THREADS); 317 } 318 319 320 321 /** 322 * Retrieves the average number of operations observed in the work queue. 323 * 324 * @return The average number of operations observed in the work queue, or 325 * {@code null} if that information was not included in the monitor 326 * entry. 327 */ 328 public Long getAverageSize() 329 { 330 return averageSize; 331 } 332 333 334 335 /** 336 * Retrieves the average number of operations observed in the work queue over 337 * a recent interval. 338 * 339 * @return The average number of operations observed in the work queue over a 340 * recent interval, or {@code null} if that information was not 341 * included in the monitor entry. 342 */ 343 public Long getRecentAverageSize() 344 { 345 return recentAverageSize; 346 } 347 348 349 350 /** 351 * Retrieves the number of operations that are currently in the work queue 352 * waiting to be processed. 353 * 354 * @return The number of operations that are currently in the work queue 355 * waiting to be processed, or {@code null} if that information was 356 * not included in the monitor entry. 357 */ 358 public Long getCurrentSize() 359 { 360 return currentSize; 361 } 362 363 364 365 /** 366 * Retrieves the maximum number of operations observed in the work queue at 367 * any given time. 368 * 369 * @return The total number of operations observed in the work queue at any 370 * given time, or {@code null} if that information was not included 371 * in the monitor entry. 372 */ 373 public Long getMaxSize() 374 { 375 return maxSize; 376 } 377 378 379 380 /** 381 * Retrieves the total number of operation requests that were rejected because 382 * the work queue was at its maximum capacity. 383 * 384 * @return The total number of operation requests rejected because the work 385 * queue was at its maximum capacity, or {@code null} if that 386 * information was not included in the monitor entry. 387 */ 388 public Long getRequestsRejectedDueToQueueFull() 389 { 390 return requestsRejected; 391 } 392 393 394 395 /** 396 * Retrieves the number of worker threads configured for the work queue. 397 * 398 * @return The number of worker threads configured for the work queue, or 399 * {@code null} if that information was not included in the monitor 400 * entry. 401 */ 402 public Long getNumWorkerThreads() 403 { 404 return numWorkerThreads; 405 } 406 407 408 409 /** 410 * Retrieves the number of worker threads that are currently busy processing 411 * an operation. 412 * 413 * @return The number of worker threads that are currently busy processing an 414 * operation, or {@code null} if that information was not included in 415 * the monitor entry. 416 */ 417 public Long getNumBusyWorkerThreads() 418 { 419 return numBusyWorkerThreads; 420 } 421 422 423 424 /** 425 * Retrieves the percentage of worker threads that are currently busy 426 * processing an operation. 427 * 428 * @return The percentage of worker threads that are currently busy 429 * processing an operation, or {@code null} if that information was 430 * not included in the monitor entry. 431 */ 432 public Long getCurrentWorkerThreadPercentBusy() 433 { 434 return currentPercentBusy; 435 } 436 437 438 439 /** 440 * Retrieves the average percentage of the time since startup that worker 441 * threads have spent busy processing operations. 442 * 443 * @return The average percentage of the time since startup that worker 444 * threads have spent busy processing operations, or {@code null} if 445 * that information was not included in the monitor entry. 446 */ 447 public Long getAverageWorkerThreadPercentBusy() 448 { 449 return averagePercentBusy; 450 } 451 452 453 454 /** 455 * Retrieves the percentage of the time over a recent interval that worker 456 * threads have spent busy processing operations. 457 * 458 * @return The percentage of the time over a recent interval that worker 459 * threads have spent busy processing operations, or {@code null} if 460 * that information was not included in the monitor entry. 461 */ 462 public Long getRecentWorkerThreadPercentBusy() 463 { 464 return recentPercentBusy; 465 } 466 467 468 469 /** 470 * Retrieves the maximum percentage of the time over any interval that worker 471 * threads have spent busy processing operations. 472 * 473 * @return The maximum percentage of the time over any interval that worker 474 * threads have spent busy processing operations, or {@code null} if 475 * that information was not included in the monitor entry. 476 */ 477 public Long getMaxWorkerThreadPercentBusy() 478 { 479 return maxPercentBusy; 480 } 481 482 483 484 /** 485 * Retrieves the average length of time in milliseconds that operations have 486 * been required to wait on the work queue before being picked up by a worker 487 * thread. 488 * 489 * @return The average length of time in milliseconds that operations have 490 * been required to wait on the work queue, or {@code null} if that 491 * information was not included in the monitor entry. 492 */ 493 public Long getAverageOperationQueueTimeMillis() 494 { 495 return averageQueueTimeMillis; 496 } 497 498 499 500 /** 501 * Retrieves the average length of time in milliseconds that 502 * recently-processed operations have been required to wait on the work queue 503 * before being picked up by a worker thread. 504 * 505 * @return The average length of time in milliseconds that recently-processed 506 * operations have been required to wait on the work queue, or 507 * {@code null} if that information was not included in the monitor 508 * entry. 509 */ 510 public Long getRecentOperationQueueTimeMillis() 511 { 512 return recentQueueTimeMillis; 513 } 514 515 516 517 /** 518 * Retrieves the number of operations that are currently waiting to be 519 * processed in the portion of the work queue reserved for operations that are 520 * part of an administrative session. 521 * 522 * @return The number of operations that are currently waiting to be 523 * processed in the portion of the work queue reserved for operations 524 * that are part of an administrative session, or {@code null} if 525 * that information was not included in the monitor entry. 526 */ 527 public Long getCurrentAdministrativeSessionQueueSize() 528 { 529 return currentAdminSize; 530 } 531 532 533 534 /** 535 * Retrieves the maximum number of operations observed in the dedicated 536 * administrative session queue at any given time. 537 * 538 * @return The total number of operations observed in the dedicated 539 * administrative session queue at any given time, or {@code null} if 540 * that information was not included in the monitor entry. 541 */ 542 public Long getMaxAdministrativeSessionQueueSize() 543 { 544 return maxAdminSize; 545 } 546 547 548 549 /** 550 * Retrieves the number of worker threads that have been reserved for 551 * processing operations that are part of an administrative session. 552 * 553 * @return The number of worker threads that have been reserved for 554 * processing operations that are part of an administrative session, 555 * or {@code null} if that information was not included in the 556 * monitor entry. 557 */ 558 public Long getNumAdministrativeSessionWorkerThreads() 559 { 560 return numAdminWorkerThreads; 561 } 562 563 564 565 /** 566 * Retrieves the number of worker threads that are currently busy processing 567 * an operation which is part of an administrative session. 568 * 569 * @return The number of worker threads that are currently busy processing an 570 * operation which is part of an administrative session, or 571 * {@code null} if that information was not included in the monitor 572 * entry. 573 */ 574 public Long getNumBusyAdministrativeSessionWorkerThreads() 575 { 576 return numBusyAdminWorkerThreads; 577 } 578 579 580 581 /** 582 * {@inheritDoc} 583 */ 584 @Override() 585 public String getMonitorDisplayName() 586 { 587 return INFO_UNBOUNDID_WORK_QUEUE_MONITOR_DISPNAME.get(); 588 } 589 590 591 592 /** 593 * {@inheritDoc} 594 */ 595 @Override() 596 public String getMonitorDescription() 597 { 598 return INFO_UNBOUNDID_WORK_QUEUE_MONITOR_DESC.get(); 599 } 600 601 602 603 /** 604 * {@inheritDoc} 605 */ 606 @Override() 607 public Map<String,MonitorAttribute> getMonitorAttributes() 608 { 609 final LinkedHashMap<String,MonitorAttribute> attrs = 610 new LinkedHashMap<String,MonitorAttribute>(); 611 612 if (requestsRejected != null) 613 { 614 addMonitorAttribute(attrs, 615 ATTR_REQUESTS_REJECTED, 616 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_REQUESTS_REJECTED.get(), 617 INFO_UNBOUNDID_WORK_QUEUE_DESC_REQUESTS_REJECTED.get(), 618 requestsRejected); 619 } 620 621 if (currentSize != null) 622 { 623 addMonitorAttribute(attrs, 624 ATTR_CURRENT_SIZE, 625 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_CURRENT_SIZE.get(), 626 INFO_UNBOUNDID_WORK_QUEUE_DESC_CURRENT_SIZE.get(), 627 currentSize); 628 } 629 630 if (recentAverageSize != null) 631 { 632 addMonitorAttribute(attrs, 633 ATTR_RECENT_AVERAGE_SIZE, 634 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_RECENT_AVERAGE_SIZE.get(), 635 INFO_UNBOUNDID_WORK_QUEUE_DESC_RECENT_AVERAGE_SIZE.get(), 636 recentAverageSize); 637 } 638 639 if (averageSize != null) 640 { 641 addMonitorAttribute(attrs, 642 ATTR_AVERAGE_SIZE, 643 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_AVERAGE_SIZE.get(), 644 INFO_UNBOUNDID_WORK_QUEUE_DESC_AVERAGE_SIZE.get(), 645 averageSize); 646 } 647 648 if (maxSize != null) 649 { 650 addMonitorAttribute(attrs, 651 ATTR_MAX_SIZE, 652 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_MAX_SIZE.get(), 653 INFO_UNBOUNDID_WORK_QUEUE_DESC_MAX_SIZE.get(), 654 maxSize); 655 } 656 657 if (numWorkerThreads != null) 658 { 659 addMonitorAttribute(attrs, 660 ATTR_NUM_WORKER_THREADS, 661 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_NUM_THREADS.get(), 662 INFO_UNBOUNDID_WORK_QUEUE_DESC_NUM_THREADS.get(), 663 numWorkerThreads); 664 } 665 666 if (numBusyWorkerThreads != null) 667 { 668 addMonitorAttribute(attrs, 669 ATTR_NUM_BUSY_WORKER_THREADS, 670 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_NUM_BUSY_THREADS.get(), 671 INFO_UNBOUNDID_WORK_QUEUE_DESC_NUM_BUSY_THREADS.get(), 672 numBusyWorkerThreads); 673 } 674 675 if (currentPercentBusy != null) 676 { 677 addMonitorAttribute(attrs, 678 ATTR_CURRENT_PCT_BUSY, 679 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_CURRENT_PCT_BUSY.get(), 680 INFO_UNBOUNDID_WORK_QUEUE_DESC_CURRENT_PCT_BUSY.get(), 681 currentPercentBusy); 682 } 683 684 if (averagePercentBusy != null) 685 { 686 addMonitorAttribute(attrs, 687 ATTR_AVERAGE_PCT_BUSY, 688 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_AVG_PCT_BUSY.get(), 689 INFO_UNBOUNDID_WORK_QUEUE_DESC_AVG_PCT_BUSY.get(), 690 averagePercentBusy); 691 } 692 693 if (recentPercentBusy != null) 694 { 695 addMonitorAttribute(attrs, 696 ATTR_RECENT_PCT_BUSY, 697 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_RECENT_PCT_BUSY.get(), 698 INFO_UNBOUNDID_WORK_QUEUE_DESC_RECENT_PCT_BUSY.get(), 699 recentPercentBusy); 700 } 701 702 if (maxPercentBusy != null) 703 { 704 addMonitorAttribute(attrs, 705 ATTR_MAX_PCT_BUSY, 706 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_MAX_PCT_BUSY.get(), 707 INFO_UNBOUNDID_WORK_QUEUE_DESC_MAX_PCT_BUSY.get(), 708 maxPercentBusy); 709 } 710 711 if (averageQueueTimeMillis != null) 712 { 713 addMonitorAttribute(attrs, 714 ATTR_AVERAGE_QUEUE_TIME_MILLIS, 715 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_AVG_QUEUE_TIME.get(), 716 INFO_UNBOUNDID_WORK_QUEUE_DESC_AVG_QUEUE_TIME.get(), 717 averageQueueTimeMillis); 718 } 719 720 if (recentQueueTimeMillis != null) 721 { 722 addMonitorAttribute(attrs, 723 ATTR_RECENT_QUEUE_TIME_MILLIS, 724 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_RECENT_QUEUE_TIME.get(), 725 INFO_UNBOUNDID_WORK_QUEUE_DESC_RECENT_QUEUE_TIME.get(), 726 recentQueueTimeMillis); 727 } 728 729 if (currentAdminSize != null) 730 { 731 addMonitorAttribute(attrs, 732 ATTR_CURRENT_ADMIN_QUEUE_SIZE, 733 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_CURRENT_ADMIN_QUEUE_SIZE.get(), 734 INFO_UNBOUNDID_WORK_QUEUE_DESC_CURRENT_ADMIN_QUEUE_SIZE.get(), 735 currentAdminSize); 736 } 737 738 if (maxAdminSize != null) 739 { 740 addMonitorAttribute(attrs, 741 ATTR_MAX_ADMIN_SESSION_QUEUE_SIZE, 742 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_MAX_ADMIN_QUEUE_SIZE.get(), 743 INFO_UNBOUNDID_WORK_QUEUE_DESC_MAX_ADMIN_QUEUE_SIZE.get(), 744 maxAdminSize); 745 } 746 747 if (numAdminWorkerThreads != null) 748 { 749 addMonitorAttribute(attrs, 750 ATTR_NUM_ADMIN_WORKER_THREADS, 751 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_NUM_ADMIN_THREADS.get(), 752 INFO_UNBOUNDID_WORK_QUEUE_DESC_NUM_ADMIN_THREADS.get(), 753 numAdminWorkerThreads); 754 } 755 756 if (numBusyAdminWorkerThreads != null) 757 { 758 addMonitorAttribute(attrs, 759 ATTR_NUM_BUSY_ADMIN_WORKER_THREADS, 760 INFO_UNBOUNDID_WORK_QUEUE_DISPNAME_NUM_BUSY_ADMIN_THREADS.get(), 761 INFO_UNBOUNDID_WORK_QUEUE_DESC_NUM_BUSY_ADMIN_THREADS.get(), 762 numBusyAdminWorkerThreads); 763 } 764 765 return Collections.unmodifiableMap(attrs); 766 } 767 }