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