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 }