001 /*
002 * Copyright 2010-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 general information about
046 * the state of an index in a Directory Server backend. Note that the term
047 * "index" may refer to a number of different things, including attribute
048 * indexes (in which each individual index type will be considered a separate
049 * index, so if "cn" has equality and substring index types then that will be
050 * considered two separate indexes), VLV indexes, and system indexes (for
051 * databases that are maintained internally, like id2entry, dn2id, id2children,
052 * and id2subtree).
053 * <BR><BR>
054 * The set of index monitor entries published by the directory server can be
055 * obtained using the {@link MonitorManager#getIndexMonitorEntries} method.
056 * Specific methods are available for accessing the associated monitor data
057 * (e.g., {@link IndexMonitorEntry#getBackendID} to retrieve the backend ID),
058 * and there are also methods for accessing this information in a generic manner
059 * (e.g., {@link IndexMonitorEntry#getMonitorAttributes} to retrieve all of
060 * the monitor attributes). See the {@link MonitorManager} class documentation
061 * for an example that demonstrates the use of the generic API for accessing
062 * monitor data.
063 */
064 @NotMutable()
065 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
066 public final class IndexMonitorEntry
067 extends MonitorEntry
068 {
069 /**
070 * The structural object class used in index monitor entries.
071 */
072 static final String INDEX_MONITOR_OC = "ds-index-monitor-entry";
073
074
075
076 /**
077 * The name of the attribute that contains the index name.
078 */
079 private static final String ATTR_INDEX_NAME = "ds-index-name";
080
081
082
083 /**
084 * The name of the attribute that contains the backend ID.
085 */
086 private static final String ATTR_BACKEND_ID = "ds-index-backend-id";
087
088
089
090 /**
091 * The name of the attribute that contains the backend base DN.
092 */
093 private static final String ATTR_BASE_DN = "ds-index-backend-base-dn";
094
095
096
097 /**
098 * The name of the attribute that contains the name of the associated
099 * attribute type.
100 */
101 private static final String ATTR_INDEX_ATTR = "ds-index-attribute-type";
102
103
104
105 /**
106 * The name of the attribute that contains the name of the associated
107 * attribute index type.
108 */
109 private static final String ATTR_INDEX_TYPE = "ds-index-type";
110
111
112
113 /**
114 * The name of the attribute that contains the string representation of a
115 * filter used for the index.
116 */
117 private static final String ATTR_INDEX_FILTER = "ds-index-filter";
118
119
120
121 /**
122 * The name of the attribute that indicates whether the index is trusted.
123 */
124 private static final String ATTR_INDEX_TRUSTED = "ds-index-trusted";
125
126
127
128 /**
129 * The name of the attribute that contains the index entry limit.
130 */
131 private static final String ATTR_ENTRY_LIMIT = "ds-index-entry-limit";
132
133
134
135 /**
136 * The name of the attribute that contains the number of index keys for which
137 * the entry count has exceeded the limit since the index DB was opened.
138 */
139 private static final String ATTR_EXCEEDED_COUNT =
140 "ds-index-exceeded-entry-limit-count-since-db-open";
141
142
143
144 /**
145 * The name of the attribute that indicates whether a matching count should be
146 * maintained for a key that has exceeded the entry limit.
147 */
148 private static final String ATTR_MAINTAIN_COUNT =
149 "ds-index-maintain-count";
150
151
152
153 /**
154 * The name of the attribute that indicates whether the index was fully
155 * primed.
156 */
157 private static final String ATTR_FULLY_PRIMED =
158 "ds-index-fully-primed-at-backend-open";
159
160
161
162 /**
163 * The name of the attribute that contains a reason explaining why the prime
164 * was not completed.
165 */
166 private static final String ATTR_PRIME_INCOMPLETE_REASON =
167 "ds-index-prime-incomplete-reason";
168
169
170
171 /**
172 * The name of the attribute that contains information about an exception that
173 * was encountered while performing the prime.
174 */
175 private static final String ATTR_PRIME_EXCEPTION =
176 "ds-index-prime-exception";
177
178
179
180 /**
181 * The name of the attribute that contains the number of keys that were
182 * primed when the backend was opened.
183 */
184 private static final String ATTR_PRIMED_KEYS =
185 "ds-index-num-primed-keys-at-backend-open";
186
187
188
189 /**
190 * The name of the attribute that contains the number of times the index has
191 * been updated since the database was opened.
192 */
193 private static final String ATTR_WRITE_COUNT =
194 "ds-index-write-count-since-db-open";
195
196
197
198 /**
199 * The name of the attribute that contains the number of keys deleted from the
200 * index since the database was opened.
201 */
202 private static final String ATTR_DELETE_COUNT =
203 "ds-index-remove-count-since-db-open";
204
205
206
207 /**
208 * The name of the attribute that contains the number of read operations
209 * against the index since the database was opened.
210 */
211 private static final String ATTR_READ_COUNT =
212 "ds-index-read-count-since-db-open";
213
214
215
216 /**
217 * The name of the attribute that contains the number of read operations
218 * performed during search filter evaluation since the database was opened.
219 */
220 private static final String ATTR_READ_FOR_SEARCH_COUNT =
221 "ds-index-read-for-search-count-since-db-open";
222
223
224
225 /**
226 * The name of the attribute that contains the number of cursors created for
227 * the index.
228 */
229 private static final String ATTR_CURSOR_COUNT =
230 "ds-index-open-cursor-count-since-db-open";
231
232
233
234 /**
235 * The serial version UID for this serializable class.
236 */
237 private static final long serialVersionUID = 9182830448328951893L;
238
239
240
241 // Indicates whether the index was fully primed when the backend came online.
242 private final Boolean fullyPrimed;
243
244 // Indicates whether the index should be considered trusted.
245 private final Boolean indexTrusted;
246
247 // Indicates whether to maintain a count of matching entries even when the ID
248 // list is not maintained.
249 private final Boolean maintainCount;
250
251 // The index entry limit for the index.
252 private final Long entryLimit;
253
254 // The number of keys that have exceeded the entry limit since coming online.
255 private final Long exceededCount;
256
257 // The number of cursors created in the index since coming online.
258 private final Long numCursors;
259
260 // The number of index keys deleted from the index since coming online.
261 private final Long numDeletes;
262
263 // The number of reads from the index since coming online.
264 private final Long numReads;
265
266 // The number of reads as a result of filter processing from the index since
267 // coming online.
268 private final Long numReadsForSearch;
269
270 // The number of writes to the index since coming online.
271 private final Long numWrites;
272
273 // The number of keys that were primed when the backend came online.
274 private final Long primedKeys;
275
276 // The name of the associated attribute type.
277 private final String attributeType;
278
279 // The name of the associated backend ID.
280 private final String backendID;
281
282 // The base DN for the associated backend.
283 private final String baseDN;
284
285 // The filter for the associated index.
286 private final String indexFilter;
287
288 // The index name for the associated index.
289 private final String indexName;
290
291 // The index name of the index type for the index.
292 private final String indexType;
293
294 // Information about an exception caught during prime processing.
295 private final String primeException;
296
297 // Information about the reason the prime was not completed.
298 private final String primeIncompleteReason;
299
300
301
302 /**
303 * Creates a new index monitor entry from the provided entry.
304 *
305 * @param entry The entry to be parsed as an index monitor entry. It must
306 * not be {@code null}.
307 */
308 public IndexMonitorEntry(final Entry entry)
309 {
310 super(entry);
311
312 fullyPrimed = getBoolean(ATTR_FULLY_PRIMED);
313 indexTrusted = getBoolean(ATTR_INDEX_TRUSTED);
314 maintainCount = getBoolean(ATTR_MAINTAIN_COUNT);
315 entryLimit = getLong(ATTR_ENTRY_LIMIT);
316 exceededCount = getLong(ATTR_EXCEEDED_COUNT);
317 numCursors = getLong(ATTR_CURSOR_COUNT);
318 numDeletes = getLong(ATTR_DELETE_COUNT);
319 numReads = getLong(ATTR_READ_COUNT);
320 numReadsForSearch = getLong(ATTR_READ_FOR_SEARCH_COUNT);
321 numWrites = getLong(ATTR_WRITE_COUNT);
322 primedKeys = getLong(ATTR_PRIMED_KEYS);
323 attributeType = getString(ATTR_INDEX_ATTR);
324 backendID = getString(ATTR_BACKEND_ID);
325 baseDN = getString(ATTR_BASE_DN);
326 indexFilter = getString(ATTR_INDEX_FILTER);
327 indexName = getString(ATTR_INDEX_NAME);
328 indexType = getString(ATTR_INDEX_TYPE);
329 primeException = getString(ATTR_PRIME_EXCEPTION);
330 primeIncompleteReason = getString(ATTR_PRIME_INCOMPLETE_REASON);
331 }
332
333
334
335 /**
336 * Retrieves the name of the index database.
337 *
338 * @return The name of the index database, or {@code null} if it was not
339 * included in the monitor entry.
340 */
341 public String getIndexName()
342 {
343 return indexName;
344 }
345
346
347
348 /**
349 * Retrieves the backend ID for the associated backend.
350 *
351 * @return The backend ID for the associated backend, or {@code null} if it
352 * was not included in the monitor entry.
353 */
354 public String getBackendID()
355 {
356 return backendID;
357 }
358
359
360
361 /**
362 * Retrieves the base DN for the data with which the index is associated.
363 *
364 * @return The base DN for the data with which the index is associated, or
365 * {@code null} if it was not included in the monitor entry.
366 */
367 public String getBaseDN()
368 {
369 return baseDN;
370 }
371
372
373
374 /**
375 * Retrieves the name of the attribute type with which the index is
376 * associated. It will only be available for attribute indexes.
377 *
378 * @return The name of the attribute type with which the index is associated,
379 * or {@code null} if it was not included in the monitor entry.
380 */
381 public String getAttributeType()
382 {
383 return attributeType;
384 }
385
386
387
388 /**
389 * Retrieves the name of the attribute index type. It will only be available
390 * for attribute indexes.
391 *
392 * @return The name of the attribute index type, or {@code null} if it was
393 * not included in the monitor entry.
394 */
395 public String getAttributeIndexType()
396 {
397 return indexType;
398 }
399
400
401
402 /**
403 * Retrieves the filter used for the index. It will only be available for
404 * filter indexes.
405 *
406 * @return The filter used for the index, or {@code null} if it was not
407 * included in the monitor entry.
408 */
409 public String getIndexFilter()
410 {
411 return indexFilter;
412 }
413
414
415
416 /**
417 * Indicates whether the index may be considered trusted. It will only be
418 * available for attribute indexes.
419 *
420 * @return {@code true} if the index may be considered trusted,
421 * {@code false} if it is not trusted, or {@code null} if it was not
422 * included in the monitor entry.
423 */
424 public Boolean isIndexTrusted()
425 {
426 return indexTrusted;
427 }
428
429
430
431 /**
432 * Retrieves the index entry limit, which is the maximum number of entries
433 * that will be allowed to match a key before the ID list for that key will
434 * stop being maintained.
435 *
436 * @return The index entry limit, or {@code null} if was not included in the
437 * monitor entry.
438 */
439 public Long getIndexEntryLimit()
440 {
441 return entryLimit;
442 }
443
444
445
446 /**
447 * Retrieves the number of index keys which have stopped being maintained
448 * because the number of matching entries has exceeded the entry limit since
449 * the index was brought online.
450 *
451 * @return The number of index keys which have exceeded the entry limit since
452 * the index was brought online, or {@code null} if it was not
453 * included in the monitor entry.
454 */
455 public Long getEntryLimitExceededCountSinceComingOnline()
456 {
457 return exceededCount;
458 }
459
460
461
462 /**
463 * Indicates whether the count of matching entries will be maintained for
464 * index keys that have exceeded the entry limit. In that case, the entry IDs
465 * for the matching entries will not be available, but the number of matching
466 * entries will be.
467 *
468 * @return {@code true} if the count of matching entries will be maintained
469 * for index keys that have exceeded the entry limit, {@code false}
470 * if not, or {@code null} if it was not included in the monitor
471 * entry.
472 */
473 public Boolean maintainCountForExceededKeys()
474 {
475 return maintainCount;
476 }
477
478
479
480 /**
481 * Indicates whether this index was fully primed when it was brought online.
482 *
483 * @return {@code true} if the index was fully primed when it was brought
484 * online, {@code false} if not, or {@code null} if it was not
485 * included in the monitor entry.
486 */
487 public Boolean fullyPrimedWhenBroughtOnline()
488 {
489 return fullyPrimed;
490 }
491
492
493
494 /**
495 * Retrieves information about the reason that the index was not fully primed
496 * when the backend was brought online (e.g., the database cache became full,
497 * the prime took too long to complete, or an exception was caught during
498 * processing).
499 *
500 * @return Information about the reason that the index was not fully primed
501 * when the backend was brought online, or {@code null} if it was not
502 * included in the monitor entry.
503 */
504 public String getPrimeIncompleteReason()
505 {
506 return primeIncompleteReason;
507 }
508
509
510
511 /**
512 * Retrieves information about any exception caught during prime processing.
513 *
514 * @return Information about any exception caught during prime processing, or
515 * {@code null} if it was not included in the monitor entry.
516 */
517 public String getPrimeException()
518 {
519 return primeException;
520 }
521
522
523
524 /**
525 * Retrieves the number of index keys that were primed when the index was
526 * brought online.
527 *
528 * @return The number of index keys that were primed when the backend was
529 * brought online, or {@code null} if it was not included in the
530 * monitor entry.
531 */
532 public Long getKeysPrimedWhenBroughtOnline()
533 {
534 return primedKeys;
535 }
536
537
538
539 /**
540 * Retrieves the number of index keys that have been inserted or replaced
541 * since the index was brought online.
542 *
543 * @return The number of index keys that have been inserted or replaced since
544 * the index was brought online, or {@code null} if it was not
545 * included in the monitor entry.
546 */
547 public Long getKeysWrittenSinceComingOnline()
548 {
549 return numWrites;
550 }
551
552
553
554 /**
555 * Retrieves the number of index keys that have been deleted since the index
556 * was brought online.
557 *
558 * @return The number of index keys that have been deleted since the index
559 * was brought online, or {@code null} if it was not included in the
560 * monitor entry.
561 */
562 public Long getKeysDeletedSinceComingOnline()
563 {
564 return numDeletes;
565 }
566
567
568
569 /**
570 * Retrieves the number of index keys that have been read since the index was
571 * brought online.
572 *
573 * @return The number of index keys that have been read since the index was
574 * brought online, or {@code null} if it was not included in the
575 * monitor entry.
576 */
577 public Long getKeysReadSinceComingOnline()
578 {
579 return numReads;
580 }
581
582
583
584 /**
585 * Retrieves the number of index reads that have been initiated because the
586 * associated attribute type was included in the filter for a search operation
587 * with a non-base scope since the index was brought online.
588 *
589 * @return The number of index reads that have been initiated as a result of
590 * filter processing, or {@code null} if it was not included in the
591 * monitor entry.
592 */
593 public Long getFilterInitiatedReadsSinceComingOnline()
594 {
595 return numReadsForSearch;
596 }
597
598
599
600 /**
601 * Retrieves the number of cursors created in the index for reading ranges of
602 * keys. Cursors may be used for processing in a variety of contexts,
603 * including processing for substring or range searches, subtree deletes,
604 * stream values operations, etc.
605 *
606 * @return The number of cursors created in the index for reading ranges of
607 * keys, or {@code null} if it was not included in the monitor entry.
608 */
609 public Long getCursorsCreatedSinceComingOnline()
610 {
611 return numCursors;
612 }
613
614
615
616 /**
617 * {@inheritDoc}
618 */
619 @Override()
620 public String getMonitorDisplayName()
621 {
622 return INFO_INDEX_MONITOR_DISPNAME.get();
623 }
624
625
626
627 /**
628 * {@inheritDoc}
629 */
630 @Override()
631 public String getMonitorDescription()
632 {
633 return INFO_INDEX_MONITOR_DESC.get();
634 }
635
636
637
638 /**
639 * {@inheritDoc}
640 */
641 @Override()
642 public Map<String,MonitorAttribute> getMonitorAttributes()
643 {
644 final LinkedHashMap<String,MonitorAttribute> attrs =
645 new LinkedHashMap<String,MonitorAttribute>(19);
646
647 if (indexName != null)
648 {
649 addMonitorAttribute(attrs,
650 ATTR_INDEX_NAME,
651 INFO_INDEX_DISPNAME_INDEX_NAME.get(),
652 INFO_INDEX_DESC_INDEX_NAME.get(),
653 indexName);
654 }
655
656 if (backendID != null)
657 {
658 addMonitorAttribute(attrs,
659 ATTR_BACKEND_ID,
660 INFO_INDEX_DISPNAME_BACKEND_ID.get(),
661 INFO_INDEX_DESC_BACKEND_ID.get(),
662 backendID);
663 }
664
665 if (baseDN != null)
666 {
667 addMonitorAttribute(attrs,
668 ATTR_BASE_DN,
669 INFO_INDEX_DISPNAME_BASE_DN.get(),
670 INFO_INDEX_DESC_BASE_DN.get(),
671 baseDN);
672 }
673
674 if (attributeType != null)
675 {
676 addMonitorAttribute(attrs,
677 ATTR_INDEX_ATTR,
678 INFO_INDEX_DISPNAME_ATTR_TYPE.get(),
679 INFO_INDEX_DESC_ATTR_TYPE.get(),
680 attributeType);
681 }
682
683 if (indexType != null)
684 {
685 addMonitorAttribute(attrs,
686 ATTR_INDEX_TYPE,
687 INFO_INDEX_DISPNAME_INDEX_TYPE.get(),
688 INFO_INDEX_DESC_INDEX_TYPE.get(),
689 indexType);
690 }
691
692 if (indexFilter != null)
693 {
694 addMonitorAttribute(attrs,
695 ATTR_INDEX_FILTER,
696 INFO_INDEX_DISPNAME_FILTER.get(),
697 INFO_INDEX_DESC_FILTER.get(),
698 indexFilter);
699 }
700
701 if (indexTrusted != null)
702 {
703 addMonitorAttribute(attrs,
704 ATTR_INDEX_TRUSTED,
705 INFO_INDEX_DISPNAME_TRUSTED.get(),
706 INFO_INDEX_DESC_TRUSTED.get(),
707 indexTrusted);
708 }
709
710 if (entryLimit != null)
711 {
712 addMonitorAttribute(attrs,
713 ATTR_ENTRY_LIMIT,
714 INFO_INDEX_DISPNAME_ENTRY_LIMIT.get(),
715 INFO_INDEX_DESC_ENTRY_LIMIT.get(),
716 entryLimit);
717 }
718
719 if (exceededCount != null)
720 {
721 addMonitorAttribute(attrs,
722 ATTR_EXCEEDED_COUNT,
723 INFO_INDEX_DISPNAME_EXCEEDED_COUNT.get(),
724 INFO_INDEX_DESC_EXCEEDED_COUNT.get(),
725 exceededCount);
726 }
727
728 if (maintainCount != null)
729 {
730 addMonitorAttribute(attrs,
731 ATTR_MAINTAIN_COUNT,
732 INFO_INDEX_DISPNAME_MAINTAIN_COUNT.get(),
733 INFO_INDEX_DESC_MAINTAIN_COUNT.get(),
734 maintainCount);
735 }
736
737 if (fullyPrimed != null)
738 {
739 addMonitorAttribute(attrs,
740 ATTR_FULLY_PRIMED,
741 INFO_INDEX_DISPNAME_FULLY_PRIMED.get(),
742 INFO_INDEX_DESC_FULLY_PRIMED.get(),
743 fullyPrimed);
744 }
745
746 if (primeIncompleteReason != null)
747 {
748 addMonitorAttribute(attrs,
749 ATTR_PRIME_INCOMPLETE_REASON,
750 INFO_INDEX_DISPNAME_PRIME_INCOMPLETE_REASON.get(),
751 INFO_INDEX_DESC_PRIME_INCOMPLETE_REASON.get(),
752 primeIncompleteReason);
753 }
754
755 if (primeException != null)
756 {
757 addMonitorAttribute(attrs,
758 ATTR_PRIME_EXCEPTION,
759 INFO_INDEX_DISPNAME_PRIME_EXCEPTION.get(),
760 INFO_INDEX_DESC_PRIME_EXCEPTION.get(),
761 primeException);
762 }
763
764 if (primedKeys != null)
765 {
766 addMonitorAttribute(attrs,
767 ATTR_PRIMED_KEYS,
768 INFO_INDEX_DISPNAME_PRIMED_KEYS.get(),
769 INFO_INDEX_DESC_PRIMED_KEYS.get(),
770 primedKeys);
771 }
772
773 if (numWrites != null)
774 {
775 addMonitorAttribute(attrs,
776 ATTR_WRITE_COUNT,
777 INFO_INDEX_DISPNAME_WRITE_COUNT.get(),
778 INFO_INDEX_DESC_WRITE_COUNT.get(),
779 numWrites);
780 }
781
782 if (numDeletes != null)
783 {
784 addMonitorAttribute(attrs,
785 ATTR_DELETE_COUNT,
786 INFO_INDEX_DISPNAME_DELETE_COUNT.get(),
787 INFO_INDEX_DESC_DELETE_COUNT.get(),
788 numDeletes);
789 }
790
791 if (numReads != null)
792 {
793 addMonitorAttribute(attrs,
794 ATTR_READ_COUNT,
795 INFO_INDEX_DISPNAME_READ_COUNT.get(),
796 INFO_INDEX_DESC_READ_COUNT.get(),
797 numReads);
798 }
799
800 if (numReadsForSearch != null)
801 {
802 addMonitorAttribute(attrs,
803 ATTR_READ_FOR_SEARCH_COUNT,
804 INFO_INDEX_DISPNAME_FILTER_INITIATED_READ_COUNT.get(),
805 INFO_INDEX_DESC_FILTER_INITIATED_READ_COUNT.get(),
806 numReadsForSearch);
807 }
808
809 if (numCursors != null)
810 {
811 addMonitorAttribute(attrs,
812 ATTR_CURSOR_COUNT,
813 INFO_INDEX_DISPNAME_CURSOR_COUNT.get(),
814 INFO_INDEX_DESC_CURSOR_COUNT.get(),
815 numCursors);
816 }
817
818 return Collections.unmodifiableMap(attrs);
819 }
820 }