001/* 002 * Copyright 2009-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2019 Ping Identity Corporation 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 */ 021package com.unboundid.ldap.sdk.unboundidds.monitors; 022 023 024 025import java.util.Collections; 026import java.util.LinkedHashMap; 027import java.util.Map; 028 029import com.unboundid.ldap.sdk.Entry; 030import com.unboundid.util.Debug; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035 036import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 037 038 039 040/** 041 * This class defines a monitor entry that provides information about the state 042 * of a replica, including the base DN, replica ID, and generation ID, as well 043 * as information about its communication with the replication server 044 * <BR> 045 * <BLOCKQUOTE> 046 * <B>NOTE:</B> This class, and other classes within the 047 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 048 * supported for use against Ping Identity, UnboundID, and 049 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 050 * for proprietary functionality or for external specifications that are not 051 * considered stable or mature enough to be guaranteed to work in an 052 * interoperable way with other types of LDAP servers. 053 * </BLOCKQUOTE> 054 * <BR> 055 * The server should present a replica monitor entry for each replicated base 056 * DN. They can be retrieved using the 057 * {@link MonitorManager#getReplicaMonitorEntries} method. These entries 058 * provide specific methods for accessing information about the replica. 059 * Alternately, this information may be accessed using the generic API. See the 060 * {@link MonitorManager} class documentation for an example that demonstrates 061 * the use of the generic API for accessing monitor data. 062 */ 063@NotMutable() 064@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 065public final class ReplicaMonitorEntry 066 extends MonitorEntry 067{ 068 /** 069 * The structural object class used in replica monitor entries. 070 */ 071 static final String REPLICA_MONITOR_OC = 072 "ds-replica-monitor-entry"; 073 074 075 076 /** 077 * The name of the attribute that contains the base DNs for the replicated 078 * data. 079 */ 080 private static final String ATTR_BASE_DN = "base-dn"; 081 082 083 084 /** 085 * The name of the attribute that contains the address and port of the 086 * replication server to which the replica is connected. 087 */ 088 private static final String ATTR_CONNECTED_TO = 089 "connected-to"; 090 091 092 093 /** 094 * The name of the attribute that provides information about the current 095 * receive window size. 096 */ 097 private static final String ATTR_CURRENT_RECEIVE_WINDOW_SIZE = 098 "current-rcv-window"; 099 100 101 102 /** 103 * The name of the attribute that provides information about the current send 104 * window size. 105 */ 106 private static final String ATTR_CURRENT_SEND_WINDOW_SIZE = 107 "current-send-window"; 108 109 110 111 /** 112 * The name of the attribute that provides the generation ID for the replica. 113 */ 114 private static final String ATTR_GENERATION_ID = "generation-id"; 115 116 117 118 /** 119 * The name of the attribute that provides information about the number of 120 * times the connection to the replication server has been lost. 121 */ 122 private static final String ATTR_LOST_CONNECTIONS = "lost-connections"; 123 124 125 126 /** 127 * The name of the attribute that provides information about the maximum 128 * receive window size. 129 */ 130 private static final String ATTR_MAX_RECEIVE_WINDOW_SIZE = 131 "max-rcv-window"; 132 133 134 135 /** 136 * The name of the attribute that provides information about the maximum send 137 * window size. 138 */ 139 private static final String ATTR_MAX_SEND_WINDOW_SIZE = 140 "max-send-window"; 141 142 143 144 /** 145 * The name of the attribute that provides information about the number of 146 * pending updates which are currently being processed by the Directory Server 147 * and have not yet been sent to the replication server. 148 */ 149 private static final String ATTR_PENDING_UPDATES = "pending-updates"; 150 151 152 153 /** 154 * The name of the attribute that provides information about the number of 155 * updates received from the replication server for this replica. 156 */ 157 private static final String ATTR_RECEIVED_UPDATES = "received-updates"; 158 159 160 161 /** 162 * The name of the attribute that provides the replica ID for this replica. 163 */ 164 private static final String ATTR_REPLICA_ID = "replica-id"; 165 166 167 168 /** 169 * The name of the attribute that provides information about the number of 170 * updates that were replayed after resolving a modify conflict. 171 */ 172 private static final String ATTR_RESOLVED_MODIFY_CONFLICTS = 173 "resolved-modify-conflicts"; 174 175 176 177 /** 178 * The name of the attribute that provides information about the number of 179 * updates that were replayed after resolving a naming conflict. 180 */ 181 private static final String ATTR_RESOLVED_NAMING_CONFLICTS = 182 "resolved-naming-conflicts"; 183 184 185 186 /** 187 * The name of the attribute that provides information about the number of 188 * updates sent to the replication server from this replica. 189 */ 190 private static final String ATTR_SENT_UPDATES = "sent-updates"; 191 192 193 194 /** 195 * The name of the attribute that indicates whether SSL is used when 196 * communicating with the replication server. 197 */ 198 private static final String ATTR_SSL_ENCRYPTION = "ssl-encryption"; 199 200 201 202 /** 203 * The name of the attribute that provides information about the number of 204 * updates that have been successfully replayed with no problems. 205 */ 206 private static final String ATTR_SUCCESSFUL_REPLAYED = "replayed-updates-ok"; 207 208 209 210 /** 211 * The name of the attribute that provides information about the total number 212 * of updates that have been replayed in some form. 213 */ 214 private static final String ATTR_TOTAL_REPLAYED = "replayed-updates"; 215 216 217 218 /** 219 * The name of the attribute that provides information about the number of 220 * updates that could not be replayed because of an unresolved naming 221 * conflict. 222 */ 223 private static final String ATTR_UNRESOLVED_NAMING_CONFLICTS = 224 "unresolved-naming-conflicts"; 225 226 227 228 /** 229 * The serial version UID for this serializable class. 230 */ 231 private static final long serialVersionUID = -9164207693317460579L; 232 233 234 235 // Indicates whether the replica uses SSL when communicating with the 236 // replication server. 237 private final Boolean useSSL; 238 239 // The current receive window size. 240 private final Long currentReceiveWindowSize; 241 242 // The current send window size. 243 private final Long currentSendWindowSize; 244 245 // The number of lost connections. 246 private final Long lostConnections; 247 248 // The maximum receive window size. 249 private final Long maxReceiveWindowSize; 250 251 // The maximum send window size. 252 private final Long maxSendWindowSize; 253 254 // The number of pending updates that haven't been sent to the replication 255 // server. 256 private final Long pendingUpdates; 257 258 // The number of updates received from the replication server. 259 private final Long receivedUpdates; 260 261 // The number of updates replayed after resolving a modify conflict. 262 private final Long replayedAfterModifyConflict; 263 264 // The number of updates replayed after resolving a naming conflict. 265 private final Long replayedAfterNamingConflict; 266 267 // The port number of the replication server. 268 private final Long replicationServerPort; 269 270 // The number of updates sent to the replication server. 271 private final Long sentUpdates; 272 273 // The number of updates replayed successfully. 274 private final Long successfullyReplayed; 275 276 // The total number of updates replayed. 277 private final Long totalReplayed; 278 279 // The number of unresolved naming conflicts that could not be successfully 280 // replayed. 281 private final Long unresolvedNamingConflicts; 282 283 // The base DN for the replicated data. 284 private final String baseDN; 285 286 // The generation ID for the replicated data. 287 private final String generationID; 288 289 // The replica ID for the replica. 290 private final String replicaID; 291 292 // The address of the replication server. 293 private final String replicationServerAddress; 294 295 296 297 /** 298 * Creates a new replica monitor entry from the provided entry. 299 * 300 * @param entry The entry to be parsed as a replica monitor entry. It must 301 * not be {@code null}. 302 */ 303 public ReplicaMonitorEntry(final Entry entry) 304 { 305 super(entry); 306 307 useSSL = getBoolean(ATTR_SSL_ENCRYPTION); 308 lostConnections = getLong(ATTR_LOST_CONNECTIONS); 309 receivedUpdates = getLong(ATTR_RECEIVED_UPDATES); 310 sentUpdates = getLong(ATTR_SENT_UPDATES); 311 pendingUpdates = getLong(ATTR_PENDING_UPDATES); 312 totalReplayed = getLong(ATTR_TOTAL_REPLAYED); 313 successfullyReplayed = getLong(ATTR_SUCCESSFUL_REPLAYED); 314 replayedAfterModifyConflict = getLong(ATTR_RESOLVED_MODIFY_CONFLICTS); 315 replayedAfterNamingConflict = getLong(ATTR_RESOLVED_NAMING_CONFLICTS); 316 unresolvedNamingConflicts = getLong(ATTR_UNRESOLVED_NAMING_CONFLICTS); 317 currentReceiveWindowSize = getLong(ATTR_CURRENT_RECEIVE_WINDOW_SIZE); 318 currentSendWindowSize = getLong(ATTR_CURRENT_SEND_WINDOW_SIZE); 319 maxReceiveWindowSize = getLong(ATTR_MAX_RECEIVE_WINDOW_SIZE); 320 maxSendWindowSize = getLong(ATTR_MAX_SEND_WINDOW_SIZE); 321 baseDN = getString(ATTR_BASE_DN); 322 generationID = getString(ATTR_GENERATION_ID); 323 replicaID = getString(ATTR_REPLICA_ID); 324 325 String addr = null; 326 Long port = null; 327 final String connectedTo = getString(ATTR_CONNECTED_TO); 328 if (connectedTo != null) 329 { 330 try 331 { 332 final int colonPos = connectedTo.indexOf(':'); 333 if (colonPos > 0) 334 { 335 addr = connectedTo.substring(0, colonPos); 336 port = Long.parseLong(connectedTo.substring(colonPos+1)); 337 } 338 } 339 catch (final Exception e) 340 { 341 Debug.debugException(e); 342 addr = null; 343 port = null; 344 } 345 } 346 347 replicationServerAddress = addr; 348 replicationServerPort = port; 349 } 350 351 352 353 /** 354 * Retrieves the base DN for this replica. 355 * 356 * @return The base DN for this replica, or {@code null} if it was not 357 * included in the monitor entry. 358 */ 359 public String getBaseDN() 360 { 361 return baseDN; 362 } 363 364 365 366 /** 367 * Retrieves the replica ID for this replica. 368 * 369 * @return The replica ID for this replica, or {@code null} if it was not 370 * included in the monitor entry. 371 */ 372 public String getReplicaID() 373 { 374 return replicaID; 375 } 376 377 378 379 /** 380 * Retrieves the generation ID for this replica. 381 * 382 * @return The generation ID for this replica, or {@code null} if it was not 383 * included in the monitor entry. 384 */ 385 public String getGenerationID() 386 { 387 return generationID; 388 } 389 390 391 392 /** 393 * Retrieves the address of the replication server to which this replica is 394 * connected. 395 * 396 * @return The address of the replication server to which this replica is 397 * connected, or {@code null} if it was not included in the monitor 398 * entry. 399 */ 400 public String getReplicationServerAddress() 401 { 402 return replicationServerAddress; 403 } 404 405 406 407 /** 408 * Retrieves the port number of the replication server to which this replica 409 * is connected. 410 * 411 * @return The port number of the replication server to which this replica is 412 * connected, or {@code null} if it was not included in the monitor 413 * entry. 414 */ 415 public Long getReplicationServerPort() 416 { 417 return replicationServerPort; 418 } 419 420 421 422 /** 423 * Indicates whether this replica uses SSL when communicating with the 424 * replication server. 425 * 426 * @return {@code Boolean.TRUE} if this replica uses SSL when communicating 427 * with the replication server, {@code Boolean.FALSE} if it does not 428 * use SSL, or {@code null} if it was not included in the monitor 429 * entry. 430 */ 431 public Boolean useSSL() 432 { 433 return useSSL; 434 } 435 436 437 438 /** 439 * Retrieves the number of times this replica has lost the connection to a 440 * replication server. 441 * 442 * @return The number of times this replica has lost the connection to a 443 * replication server, or {@code null} if it was not included in the 444 * monitor entry. 445 */ 446 public Long getLostConnections() 447 { 448 return lostConnections; 449 } 450 451 452 453 /** 454 * Retrieves the number of updates that this replica has received from the 455 * replication server. 456 * 457 * @return The number of updates that this replica has received from the 458 * replication server, or {@code null} if it was not included in the 459 * monitor entry. 460 */ 461 public Long getReceivedUpdates() 462 { 463 return receivedUpdates; 464 } 465 466 467 468 /** 469 * Retrieves the number of updates that this replica has sent to the 470 * replication server. 471 * 472 * @return The number of updates that this replica has sent to the 473 * replication server, or {@code null} if it was not included in the 474 * monitor entry. 475 */ 476 public Long getSentUpdates() 477 { 478 return sentUpdates; 479 } 480 481 482 483 /** 484 * Retrieves the number of updates that are currently in progress in the 485 * Directory Server and have not yet been sent to the replication server. 486 * 487 * @return The number of updates that are currently in progress in the 488 * Directory Server and have not yet been sent to the replication 489 * server, or {@code null} if it was not included in the monitor 490 * entry. 491 */ 492 public Long getPendingUpdates() 493 { 494 return pendingUpdates; 495 } 496 497 498 499 /** 500 * Retrieves the total number of updates that have been replayed in this 501 * replica. 502 * 503 * @return The total number of updates that have been replayed in this 504 * replica, or {@code null} if it was not included in the monitor 505 * entry. 506 */ 507 public Long getTotalUpdatesReplayed() 508 { 509 return totalReplayed; 510 } 511 512 513 514 /** 515 * Retrieves the number of updates that have been successfully replayed in 516 * this replica without conflicts. 517 * 518 * @return The number of updates that have been successfully replayed in this 519 * replica without conflicts, or {@code null} if it was not included 520 * in the monitor entry. 521 */ 522 public Long getUpdatesSuccessfullyReplayed() 523 { 524 return successfullyReplayed; 525 } 526 527 528 529 /** 530 * Retrieves the number of updates that have been replayed in this replica 531 * after automatically resolving a modify conflict. 532 * 533 * @return The number of updates that have been replayed in this replica 534 * after automatically resolving a modify conflict, or {@code null} 535 * if it was not included in the monitor entry. 536 */ 537 public Long getUpdatesReplayedAfterModifyConflict() 538 { 539 return replayedAfterModifyConflict; 540 } 541 542 543 544 /** 545 * Retrieves the number of updates that have been replayed in this replica 546 * after automatically resolving a naming conflict. 547 * 548 * @return The number of updates that have been replayed in this replica 549 * after automatically resolving a naming conflict, or {@code null} 550 * if it was not included in the monitor entry. 551 */ 552 public Long getUpdatesReplayedAfterNamingConflict() 553 { 554 return replayedAfterNamingConflict; 555 } 556 557 558 559 /** 560 * Retrieves the number of updates that could not be replayed as a result of a 561 * naming conflict that could not be automatically resolved. 562 * 563 * @return The number of updates that could not be replayed as a result of a 564 * naming conflict that could not be automatically resolved, or 565 * {@code null} if it was not included in the monitor entry. 566 */ 567 public Long getUnresolvedNamingConflicts() 568 { 569 return unresolvedNamingConflicts; 570 } 571 572 573 574 /** 575 * Retrieves the current receive window size for this replica. 576 * 577 * @return The current receive window size for this replica, or {@code null} 578 * if it was not included in the monitor entry. 579 */ 580 public Long getCurrentReceiveWindowSize() 581 { 582 return currentReceiveWindowSize; 583 } 584 585 586 587 /** 588 * Retrieves the current send window size for this replica. 589 * 590 * @return The current send window size for this replica, or {@code null} if 591 * it was not included in the monitor entry. 592 */ 593 public Long getCurrentSendWindowSize() 594 { 595 return currentSendWindowSize; 596 } 597 598 599 600 /** 601 * Retrieves the maximum receive window size for this replica. 602 * 603 * @return The maximum receive window size for this replica, or {@code null} 604 * if it was not included in the monitor entry. 605 */ 606 public Long getMaximumReceiveWindowSize() 607 { 608 return maxReceiveWindowSize; 609 } 610 611 612 613 /** 614 * Retrieves the maximum send window size for this replica. 615 * 616 * @return The maximum send window size for this replica, or {@code null} if 617 * it was not included in the monitor entry. 618 */ 619 public Long getMaximumSendWindowSize() 620 { 621 return maxSendWindowSize; 622 } 623 624 625 626 /** 627 * {@inheritDoc} 628 */ 629 @Override() 630 public String getMonitorDisplayName() 631 { 632 return INFO_REPLICA_MONITOR_DISPNAME.get(); 633 } 634 635 636 637 /** 638 * {@inheritDoc} 639 */ 640 @Override() 641 public String getMonitorDescription() 642 { 643 return INFO_REPLICA_MONITOR_DESC.get(); 644 } 645 646 647 648 /** 649 * {@inheritDoc} 650 */ 651 @Override() 652 public Map<String,MonitorAttribute> getMonitorAttributes() 653 { 654 final LinkedHashMap<String,MonitorAttribute> attrs = 655 new LinkedHashMap<>(StaticUtils.computeMapCapacity(30)); 656 657 if (baseDN != null) 658 { 659 addMonitorAttribute(attrs, 660 ATTR_BASE_DN, 661 INFO_REPLICA_DISPNAME_BASE_DN.get(), 662 INFO_REPLICA_DESC_BASE_DN.get(), 663 baseDN); 664 } 665 666 if (replicaID != null) 667 { 668 addMonitorAttribute(attrs, 669 ATTR_REPLICA_ID, 670 INFO_REPLICA_DISPNAME_REPLICA_ID.get(), 671 INFO_REPLICA_DESC_REPLICA_ID.get(), 672 replicaID); 673 } 674 675 if (generationID != null) 676 { 677 addMonitorAttribute(attrs, 678 ATTR_GENERATION_ID, 679 INFO_REPLICA_DISPNAME_GENERATION_ID.get(), 680 INFO_REPLICA_DESC_GENERATION_ID.get(), 681 generationID); 682 } 683 684 if (replicationServerAddress != null) 685 { 686 addMonitorAttribute(attrs, 687 ATTR_CONNECTED_TO, 688 INFO_REPLICA_DISPNAME_CONNECTED_TO.get(), 689 INFO_REPLICA_DESC_CONNECTED_TO.get(), 690 replicationServerAddress + ':' + replicationServerPort); 691 } 692 693 if (useSSL != null) 694 { 695 addMonitorAttribute(attrs, 696 ATTR_SSL_ENCRYPTION, 697 INFO_REPLICA_DISPNAME_USE_SSL.get(), 698 INFO_REPLICA_DESC_USE_SSL.get(), 699 useSSL); 700 } 701 702 if (lostConnections != null) 703 { 704 addMonitorAttribute(attrs, 705 ATTR_LOST_CONNECTIONS, 706 INFO_REPLICA_DISPNAME_LOST_CONNECTIONS.get(), 707 INFO_REPLICA_DESC_LOST_CONNECTIONS.get(), 708 lostConnections); 709 } 710 711 if (receivedUpdates != null) 712 { 713 addMonitorAttribute(attrs, 714 ATTR_RECEIVED_UPDATES, 715 INFO_REPLICA_DISPNAME_RECEIVED_UPDATES.get(), 716 INFO_REPLICA_DESC_RECEIVED_UPDATES.get(), 717 receivedUpdates); 718 } 719 720 if (sentUpdates != null) 721 { 722 addMonitorAttribute(attrs, 723 ATTR_SENT_UPDATES, 724 INFO_REPLICA_DISPNAME_SENT_UPDATES.get(), 725 INFO_REPLICA_DESC_SENT_UPDATES.get(), 726 sentUpdates); 727 } 728 729 if (pendingUpdates != null) 730 { 731 addMonitorAttribute(attrs, 732 ATTR_PENDING_UPDATES, 733 INFO_REPLICA_DISPNAME_PENDING_UPDATES.get(), 734 INFO_REPLICA_DESC_PENDING_UPDATES.get(), 735 pendingUpdates); 736 } 737 738 if (totalReplayed != null) 739 { 740 addMonitorAttribute(attrs, 741 ATTR_TOTAL_REPLAYED, 742 INFO_REPLICA_DISPNAME_TOTAL_REPLAYED.get(), 743 INFO_REPLICA_DESC_TOTAL_REPLAYED.get(), 744 totalReplayed); 745 } 746 747 if (successfullyReplayed != null) 748 { 749 addMonitorAttribute(attrs, 750 ATTR_SUCCESSFUL_REPLAYED, 751 INFO_REPLICA_DISPNAME_SUCCESSFUL_REPLAYED.get(), 752 INFO_REPLICA_DESC_SUCCESSFUL_REPLAYED.get(), 753 successfullyReplayed); 754 } 755 756 if (replayedAfterModifyConflict != null) 757 { 758 addMonitorAttribute(attrs, 759 ATTR_RESOLVED_MODIFY_CONFLICTS, 760 INFO_REPLICA_DISPNAME_RESOLVED_MODIFY_CONFLICTS.get(), 761 INFO_REPLICA_DESC_RESOLVED_MODIFY_CONFLICTS.get(), 762 replayedAfterModifyConflict); 763 } 764 765 if (replayedAfterNamingConflict != null) 766 { 767 addMonitorAttribute(attrs, 768 ATTR_RESOLVED_NAMING_CONFLICTS, 769 INFO_REPLICA_DISPNAME_RESOLVED_NAMING_CONFLICTS.get(), 770 INFO_REPLICA_DESC_RESOLVED_NAMING_CONFLICTS.get(), 771 replayedAfterNamingConflict); 772 } 773 774 if (unresolvedNamingConflicts != null) 775 { 776 addMonitorAttribute(attrs, 777 ATTR_UNRESOLVED_NAMING_CONFLICTS, 778 INFO_REPLICA_DISPNAME_UNRESOLVED_NAMING_CONFLICTS.get(), 779 INFO_REPLICA_DESC_UNRESOLVED_NAMING_CONFLICTS.get(), 780 unresolvedNamingConflicts); 781 } 782 783 if (currentReceiveWindowSize != null) 784 { 785 addMonitorAttribute(attrs, 786 ATTR_CURRENT_RECEIVE_WINDOW_SIZE, 787 INFO_REPLICA_DISPNAME_CURRENT_RECEIVE_WINDOW_SIZE.get(), 788 INFO_REPLICA_DESC_CURRENT_RECEIVE_WINDOW_SIZE.get(), 789 currentReceiveWindowSize); 790 } 791 792 if (currentSendWindowSize != null) 793 { 794 addMonitorAttribute(attrs, 795 ATTR_CURRENT_SEND_WINDOW_SIZE, 796 INFO_REPLICA_DISPNAME_CURRENT_SEND_WINDOW_SIZE.get(), 797 INFO_REPLICA_DESC_CURRENT_SEND_WINDOW_SIZE.get(), 798 currentSendWindowSize); 799 } 800 801 if (maxReceiveWindowSize != null) 802 { 803 addMonitorAttribute(attrs, 804 ATTR_MAX_RECEIVE_WINDOW_SIZE, 805 INFO_REPLICA_DISPNAME_MAX_RECEIVE_WINDOW_SIZE.get(), 806 INFO_REPLICA_DESC_MAX_RECEIVE_WINDOW_SIZE.get(), 807 maxReceiveWindowSize); 808 } 809 810 if (maxSendWindowSize != null) 811 { 812 addMonitorAttribute(attrs, 813 ATTR_MAX_SEND_WINDOW_SIZE, 814 INFO_REPLICA_DISPNAME_MAX_SEND_WINDOW_SIZE.get(), 815 INFO_REPLICA_DESC_MAX_SEND_WINDOW_SIZE.get(), 816 maxSendWindowSize); 817 } 818 819 return Collections.unmodifiableMap(attrs); 820 } 821}