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