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