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 }