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.io.Serializable;
026import java.util.Date;
027
028import com.unboundid.util.NotMutable;
029import com.unboundid.util.ThreadSafety;
030import com.unboundid.util.ThreadSafetyLevel;
031
032import static com.unboundid.util.Debug.*;
033import static com.unboundid.util.StaticUtils.*;
034
035
036
037/**
038 * This class provides a data structure that contains information about a
039 * replica contained in a replication summary monitor entry.
040 * <BR>
041 * <BLOCKQUOTE>
042 *   <B>NOTE:</B>  This class, and other classes within the
043 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
044 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
045 *   server products.  These classes provide support for proprietary
046 *   functionality or for external specifications that are not considered stable
047 *   or mature enough to be guaranteed to work in an interoperable way with
048 *   other types of LDAP servers.
049 * </BLOCKQUOTE>
050 */
051@NotMutable()
052@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
053public final class ReplicationSummaryReplica
054       implements Serializable
055{
056  /**
057   * The serial version UID for this serializable class.
058   */
059  private static final long serialVersionUID = 5967001261856109688L;
060
061
062
063  // The date of the oldest backlog change.
064  private final Date oldestBacklogChangeDate;
065
066  // The LDAP server port for this replica.
067  private final Long ldapServerPort;
068
069  // The replication backlog, presented as the number of missing changes in the
070  // replica.
071  private final Long replicationBacklog;
072
073  // The peak update rate in operations per second.
074  private final Long peakUpdateRate;
075
076  // The recent update rate in operations per second.
077  private final Long recentUpdateRate;
078
079  // The generation ID for the data in the replica.
080  private final String generationID;
081
082  // The LDAP server address for this replica.
083  private final String ldapServerAddress;
084
085  // The replica ID for this replica.
086  private final String replicaID;
087
088  // The replication server ID for the replication server to which this replica
089  // is connected.
090  private final String replicationServerID;
091
092  // The value used to create this replication summary replica object.
093  private final String stringRepresentation;
094
095
096
097  /**
098   * Creates a new replication summary replica object from the provided string
099   * representation.
100   *
101   * @param  value  The value string to be parsed as a replication summary
102   *                replica object.
103   */
104  public ReplicationSummaryReplica(final String value)
105  {
106    stringRepresentation = value;
107
108    replicaID           = getElementValue(value, "replica-id");
109    replicationServerID = getElementValue(value, "connected-to");
110    generationID        = getElementValue(value, "generation-id");
111
112    final String hostPort = getElementValue(value, "ldap-server");
113    if (hostPort == null)
114    {
115      ldapServerAddress = null;
116      ldapServerPort    = null;
117    }
118    else
119    {
120      Long p;
121      String a;
122
123      try
124      {
125        final int colonPos = hostPort.indexOf(':');
126        a = hostPort.substring(0, colonPos);
127        p = Long.parseLong(hostPort.substring(colonPos+1));
128      }
129      catch (final Exception e)
130      {
131        debugException(e);
132        a = null;
133        p = null;
134      }
135
136      ldapServerAddress = a;
137      ldapServerPort    = p;
138    }
139
140    String replicationBacklogStr =
141            getElementValue(value, "replication-backlog");
142    if (replicationBacklogStr == null)
143    {
144      // missing-changes was renamed to replication-backlog, so we check
145      // for missing-changes to maintain backwards compatibility.
146      replicationBacklogStr = getElementValue(value, "missing-changes");
147    }
148
149    if (replicationBacklogStr == null)
150    {
151      replicationBacklog = null;
152    }
153    else
154    {
155      Long mc;
156
157      try
158      {
159        mc = Long.parseLong(replicationBacklogStr);
160      }
161      catch (final Exception e)
162      {
163        debugException(e);
164        mc = null;
165      }
166
167      replicationBacklog = mc;
168    }
169
170    String rateStr = getElementValue(value, "recent-update-rate");
171    if (rateStr == null)
172    {
173      recentUpdateRate = null;
174    }
175    else
176    {
177      Long r;
178      try
179      {
180        final int slashPos = rateStr.indexOf('/');
181        r = Long.parseLong(rateStr.substring(0, slashPos));
182      }
183      catch (final Exception e)
184      {
185        debugException(e);
186        r = null;
187      }
188      recentUpdateRate = r;
189    }
190
191    rateStr = getElementValue(value, "peak-update-rate");
192    if (rateStr == null)
193    {
194      peakUpdateRate = null;
195    }
196    else
197    {
198      Long r;
199      try
200      {
201        final int slashPos = rateStr.indexOf('/');
202        r = Long.parseLong(rateStr.substring(0, slashPos));
203      }
204      catch (final Exception e)
205      {
206        debugException(e);
207        r = null;
208      }
209      peakUpdateRate = r;
210    }
211
212    String dateStr =
213         getElementValue(value, "age-of-oldest-backlog-change");
214    if (dateStr == null)
215    {
216      // age-of-oldest-missing-change was renamed to
217      // age-of-oldest-backlog-change, so we check
218      // for age-of-oldest-missing-change to maintain backwards compatibility.
219      dateStr = getElementValue(value, "age-of-oldest-missing-change");
220    }
221
222    if (dateStr == null)
223    {
224      oldestBacklogChangeDate = null;
225    }
226    else
227    {
228      Date d;
229
230      try
231      {
232        final int spacePos = dateStr.indexOf(' ');
233        d = decodeGeneralizedTime(dateStr.substring(0, spacePos));
234      }
235      catch (final Exception e)
236      {
237        debugException(e);
238        d = null;
239      }
240
241      oldestBacklogChangeDate = d;
242    }
243  }
244
245
246
247  /**
248   * Retrieves the value for the specified element in the replica string.
249   *
250   * @param  s  The string to be parsed.
251   * @param  n  The name of the element for which to retrieve the value.
252   *
253   * @return  The value for the specified element in the replica string, or
254   *          {@code null} if it was not present, could not be determined, or
255   *          was an empty string.
256   */
257  private static String getElementValue(final String s, final String n)
258  {
259    final String nPlusEQ = n + "=\"";
260
261    int pos = s.indexOf(nPlusEQ);
262    if (pos < 0)
263    {
264      return null;
265    }
266    pos += nPlusEQ.length();
267
268    final int closePos = s.indexOf('"', pos);
269    if (closePos <= pos)
270    {
271      return null;
272    }
273
274    return s.substring(pos, closePos);
275  }
276
277
278
279  /**
280   * Retrieves the replica ID for this replica.
281   *
282   * @return  The replica ID for this replica, or {@code null} if that
283   *          information is not available.
284   */
285  public String getReplicaID()
286  {
287    return replicaID;
288  }
289
290
291
292  /**
293   * Retrieves the address used to communicate with this replica via LDAP.
294   *
295   * @return  The address used to communicate with this replica via LDAP, or
296   *          {@code null} if that information is not available.
297   */
298  public String getLDAPServerAddress()
299  {
300    return ldapServerAddress;
301  }
302
303
304
305  /**
306   * Retrieves the port number used to communicate with this replica via LDAP.
307   *
308   * @return  The port number used to communicate with this replica via LDAP, or
309   *          {@code null} if that information is not available.
310   */
311  public Long getLDAPServerPort()
312  {
313    return ldapServerPort;
314  }
315
316
317
318  /**
319   * Retrieves the replication server ID for the replication server to which
320   * this replica is connected.
321   *
322   * @return  The replication server ID for the replication server to which this
323   *          replica is connected, or {@code null} if that information is not
324   *          available.
325   */
326  public String getReplicationServerID()
327  {
328    return replicationServerID;
329  }
330
331
332
333  /**
334   * Retrieves the generation ID for this replica.
335   *
336   * @return  The generation ID for this replica, or {@code null} if that
337   *          information is not available.
338   */
339  public String getGenerationID()
340  {
341    return generationID;
342  }
343
344
345
346  /**
347   * Retrieves the recent update rate for this replica in operations per second.
348   *
349   * @return  The recent update rate for this replica in operations per second,
350   *          or {@code null} if that information is not available.
351   */
352  public Long getRecentUpdateRate()
353  {
354    return recentUpdateRate;
355  }
356
357
358
359  /**
360   * Retrieves the peak update rate for this replica in operations per second.
361   *
362   * @return  The peak update rate for this replica in operations per second, or
363   *          {@code null} if that information is not available.
364   */
365  public Long getPeakUpdateRate()
366  {
367    return peakUpdateRate;
368  }
369
370
371
372  /**
373   * Retrieves the replication backlog, represented as the number of missing
374   * changes, for this replica.
375   *
376   * @return  The replication backlog, represented as the number of missing
377   *          changes, for this replica , or {@code null} if
378   *          that information is not available.
379   *
380   * @deprecated  Use {@link #getReplicationBacklog()} instead.
381   */
382  @Deprecated
383  public Long getMissingChanges()
384  {
385    return getReplicationBacklog();
386  }
387
388
389
390  /**
391   * Retrieves the replication backlog, represented as the number of missing
392   * changes, for this replica.
393   *
394   * @return  The replication backlog, represented as the number of missing
395   *          changes, for this replica , or {@code null} if
396   *          that information is not available.
397   */
398  public Long getReplicationBacklog()
399  {
400    return replicationBacklog;
401  }
402
403
404
405  /**
406   * Retrieves the date of the oldest backlog change for this replica.
407   *
408   * @return  The date of the oldest backlog change for this replica, or
409   *          {@code null} if that information is not available or there are no
410   *          backlog changes.
411   *
412   * @deprecated  Use {@link #getOldestBacklogChangeDate()} instead.
413   */
414  @Deprecated
415  public Date getOldestMissingChangeDate()
416  {
417    return getOldestBacklogChangeDate();
418  }
419
420
421
422  /**
423   * Retrieves the date of the oldest backlog change for this replica.
424   *
425   * @return  The date of the oldest backlog change for this replica, or
426   *          {@code null} if that information is not available or there are no
427   *          backlog changes.
428   */
429  public Date getOldestBacklogChangeDate()
430  {
431    return oldestBacklogChangeDate;
432  }
433
434
435
436  /**
437   * Retrieves a string representation of this replication summary replica.
438   *
439   * @return  A string representation of this replication summary replica.
440   */
441  @Override()
442  public String toString()
443  {
444    return stringRepresentation;
445  }
446}