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.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}