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