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 }