001/* 002 * Copyright 2008-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.util.Collections; 026import java.util.List; 027import java.util.LinkedHashMap; 028import java.util.Map; 029 030import com.unboundid.ldap.sdk.Entry; 031import com.unboundid.util.Debug; 032import com.unboundid.util.DebugType; 033import com.unboundid.util.NotMutable; 034import com.unboundid.util.ThreadSafety; 035import com.unboundid.util.ThreadSafetyLevel; 036 037import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 038 039 040 041/** 042 * This class defines a monitor entry that provides general information about a 043 * Directory Server backend. 044 * <BR> 045 * <BLOCKQUOTE> 046 * <B>NOTE:</B> This class, and other classes within the 047 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 048 * supported for use against Ping Identity, UnboundID, and 049 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 050 * for proprietary functionality or for external specifications that are not 051 * considered stable or mature enough to be guaranteed to work in an 052 * interoperable way with other types of LDAP servers. 053 * </BLOCKQUOTE> 054 * <BR> 055 * Information that may be available in a backend monitor entry includes: 056 * <UL> 057 * <LI>The backend ID for the backend.</LI> 058 * <LI>The set of base DNs for the backend.</LI> 059 * <LI>The total number of entries in the backend.</LI> 060 * <LI>The number of entries in the backend per base DN.</LI> 061 * <LI>The writability mode for the backend, which indicates whether it will 062 * accept write operations.</LI> 063 * <LI>An indication about whether the backend is public (intended to hold 064 * user data) or private (intended to hold operational data).</LI> 065 * </UL> 066 * The set of backend monitor entries published by the directory server can be 067 * obtained using the {@link MonitorManager#getBackendMonitorEntries} method. 068 * Specific methods are available for accessing the associated monitor data 069 * (e.g., {@link BackendMonitorEntry#getBackendID} to retrieve the backend ID), 070 * and there are also methods for accessing this information in a generic manner 071 * (e.g., {@link BackendMonitorEntry#getMonitorAttributes} to retrieve all of 072 * the monitor attributes). See the {@link MonitorManager} class documentation 073 * for an example that demonstrates the use of the generic API for accessing 074 * monitor data. 075 */ 076@NotMutable() 077@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 078public final class BackendMonitorEntry 079 extends MonitorEntry 080{ 081 /** 082 * The structural object class used in backend monitor entries. 083 */ 084 static final String BACKEND_MONITOR_OC = "ds-backend-monitor-entry"; 085 086 087 088 /** 089 * The name of the attribute that contains the backend ID. 090 */ 091 private static final String ATTR_BACKEND_ID = "ds-backend-id"; 092 093 094 095 /** 096 * The name of the attribute that specifies the base DN(s) for the backend. 097 */ 098 private static final String ATTR_BASE_DN = "ds-backend-base-dn"; 099 100 101 102 /** 103 * The name of the attribute that specifies the number of entries per base DN 104 * in the backend. 105 */ 106 private static final String ATTR_ENTRIES_PER_BASE_DN = 107 "ds-base-dn-entry-count"; 108 109 110 111 /** 112 * The name of the attribute that indicates whether the backend is a private 113 * backend. 114 */ 115 private static final String ATTR_IS_PRIVATE = "ds-backend-is-private"; 116 117 118 119 /** 120 * The name of the attribute that holds the number of soft deletes processed 121 * since the backend was initialized. 122 */ 123 private static final String ATTR_SOFT_DELETE_COUNT = 124 "ds-soft-delete-operations-count"; 125 126 127 128 /** 129 * The name of the attribute that specifies the total number of entries in the 130 * backend. 131 */ 132 private static final String ATTR_TOTAL_ENTRIES = "ds-backend-entry-count"; 133 134 135 136 /** 137 * The name of the attribute that holds the number of undeletes processed 138 * since the backend was initialized. 139 */ 140 private static final String ATTR_UNDELETE_COUNT = 141 "ds-undelete-operations-count"; 142 143 144 145 /** 146 * The name of the attribute that specifies the writability mode for the 147 * backend. 148 */ 149 private static final String ATTR_WRITABILITY_MODE = 150 "ds-backend-writability-mode"; 151 152 153 154 /** 155 * The serial version UID for this serializable class. 156 */ 157 private static final long serialVersionUID = -4256944695436807547L; 158 159 160 161 // Indicates whether the backend is a private backend. 162 private final Boolean isPrivate; 163 164 // The base DNs for the backend. 165 private final List<String> baseDNs; 166 167 // The number of soft delete operations processed since the backend was 168 // started. 169 private final Long softDeleteCount; 170 171 // The total number of entries in the backend. 172 private final Long totalEntries; 173 174 // The number of undelete operations processed since the backend was started. 175 private final Long undeleteCount; 176 177 // The number of entries per base DN in the backend. 178 private final Map<String,Long> entriesPerBaseDN; 179 180 // The backend ID for the backend. 181 private final String backendID; 182 183 // The writability mode for the backend. 184 private final String writabilityMode; 185 186 187 188 /** 189 * Creates a new backend monitor entry from the provided entry. 190 * 191 * @param entry The entry to be parsed as a backend monitor entry. It must 192 * not be {@code null}. 193 */ 194 public BackendMonitorEntry(final Entry entry) 195 { 196 super(entry); 197 198 backendID = getString(ATTR_BACKEND_ID); 199 baseDNs = getStrings(ATTR_BASE_DN); 200 isPrivate = getBoolean(ATTR_IS_PRIVATE); 201 softDeleteCount = getLong(ATTR_SOFT_DELETE_COUNT); 202 totalEntries = getLong(ATTR_TOTAL_ENTRIES); 203 undeleteCount = getLong(ATTR_UNDELETE_COUNT); 204 writabilityMode = getString(ATTR_WRITABILITY_MODE); 205 206 final List<String> entriesPerBase = getStrings(ATTR_ENTRIES_PER_BASE_DN); 207 final LinkedHashMap<String,Long> countMap = 208 new LinkedHashMap<>(entriesPerBase.size()); 209 for (final String s : entriesPerBase) 210 { 211 try 212 { 213 final int spacePos = s.indexOf(' '); 214 final Long l = Long.parseLong(s.substring(0, spacePos)); 215 final String dn = s.substring(spacePos+1).trim(); 216 countMap.put(dn, l); 217 } 218 catch (final Exception e) 219 { 220 Debug.debugException(e); 221 222 if (Debug.debugEnabled(DebugType.MONITOR)) 223 { 224 Debug.debugMonitor(entry, 225 "Cannot parse value '" + s + "' for attribute " + 226 ATTR_ENTRIES_PER_BASE_DN); 227 } 228 } 229 } 230 231 entriesPerBaseDN = Collections.unmodifiableMap(countMap); 232 } 233 234 235 236 /** 237 * Retrieves the backend ID for the associated backend. 238 * 239 * @return The backend ID for the associated backend, or {@code null} if it 240 * was not included in the monitor entry. 241 */ 242 public String getBackendID() 243 { 244 return backendID; 245 } 246 247 248 249 /** 250 * Retrieves the base DNs for the associated backend. 251 * 252 * @return The base DNs for the associated backend, or an empty list if it 253 * was not included in the monitor entry. 254 */ 255 public List<String> getBaseDNs() 256 { 257 return baseDNs; 258 } 259 260 261 262 /** 263 * Indicates whether the associated backend is a private backend. 264 * 265 * @return {@code Boolean.TRUE} if the backend is a private backend, 266 * {@code Boolean.FALSE} if it is not a private backend, or 267 * {@code null} if it was not included in the monitor entry. 268 */ 269 public Boolean isPrivate() 270 { 271 return isPrivate; 272 } 273 274 275 276 /** 277 * Retrieves the writability mode for the associated backend. 278 * 279 * @return The writability mode for the associated backend, or {@code null} 280 * if it was not included in the monitor entry. 281 */ 282 public String getWritabilityMode() 283 { 284 return writabilityMode; 285 } 286 287 288 289 /** 290 * Retrieves the total number of entries in the associated backend. 291 * 292 * @return The total number of entries in the associated backend, or 293 * {@code null} if it was not included in the monitor entry. 294 */ 295 public Long getTotalEntries() 296 { 297 return totalEntries; 298 } 299 300 301 302 /** 303 * Retrieves a count of the number of entries per base DN in the associated 304 * backend. 305 * 306 * @return A count of the number of entries per base DN in the associated 307 * backend, or an empty map if it was not included in the monitor 308 * entry. 309 */ 310 public Map<String,Long> getEntriesPerBaseDN() 311 { 312 return entriesPerBaseDN; 313 } 314 315 316 317 /** 318 * Retrieves the number of soft delete operations processed in the backend 319 * since the backend was started. 320 * 321 * @return The number of soft delete operations processed in the backend 322 * since the backend was started, or {@code null} if it was not 323 * included in the monitor entry. 324 */ 325 public Long getSoftDeleteCount() 326 { 327 return softDeleteCount; 328 } 329 330 331 332 /** 333 * Retrieves the number of undelete operations processed in the backend since 334 * the backend was started. 335 * 336 * @return The number of undelete operations processed in the backend since 337 * the backend was started, or {@code null} if it was not included in 338 * the monitor entry. 339 */ 340 public Long getUndeleteCount() 341 { 342 return undeleteCount; 343 } 344 345 346 347 /** 348 * {@inheritDoc} 349 */ 350 @Override() 351 public String getMonitorDisplayName() 352 { 353 return INFO_BACKEND_MONITOR_DISPNAME.get(); 354 } 355 356 357 358 /** 359 * {@inheritDoc} 360 */ 361 @Override() 362 public String getMonitorDescription() 363 { 364 return INFO_BACKEND_MONITOR_DESC.get(); 365 } 366 367 368 369 /** 370 * {@inheritDoc} 371 */ 372 @Override() 373 public Map<String,MonitorAttribute> getMonitorAttributes() 374 { 375 final LinkedHashMap<String,MonitorAttribute> attrs = 376 new LinkedHashMap<>(20); 377 378 if (backendID != null) 379 { 380 addMonitorAttribute(attrs, 381 ATTR_BACKEND_ID, 382 INFO_BACKEND_DISPNAME_BACKEND_ID.get(), 383 INFO_BACKEND_DESC_BACKEND_ID.get(), 384 backendID); 385 } 386 387 if (! baseDNs.isEmpty()) 388 { 389 addMonitorAttribute(attrs, 390 ATTR_BASE_DN, 391 INFO_BACKEND_DISPNAME_BASE_DN.get(), 392 INFO_BACKEND_DESC_BASE_DN.get(), 393 baseDNs); 394 } 395 396 if (totalEntries != null) 397 { 398 addMonitorAttribute(attrs, 399 ATTR_TOTAL_ENTRIES, 400 INFO_BACKEND_DISPNAME_TOTAL_ENTRIES.get(), 401 INFO_BACKEND_DESC_TOTAL_ENTRIES.get(), 402 totalEntries); 403 } 404 405 for (final String baseDN : entriesPerBaseDN.keySet()) 406 { 407 final Long count = entriesPerBaseDN.get(baseDN); 408 addMonitorAttribute(attrs, 409 ATTR_ENTRIES_PER_BASE_DN + '-' + baseDN, 410 INFO_BACKEND_DISPNAME_ENTRY_COUNT.get(baseDN), 411 INFO_BACKEND_DESC_ENTRY_COUNT.get(baseDN), 412 count); 413 414 } 415 416 if (softDeleteCount != null) 417 { 418 addMonitorAttribute(attrs, 419 ATTR_SOFT_DELETE_COUNT, 420 INFO_BACKEND_DISPNAME_SOFT_DELETE_COUNT.get(), 421 INFO_BACKEND_DESC_SOFT_DELETE_COUNT.get(), 422 softDeleteCount); 423 } 424 425 if (undeleteCount != null) 426 { 427 addMonitorAttribute(attrs, 428 ATTR_UNDELETE_COUNT, 429 INFO_BACKEND_DISPNAME_UNDELETE_COUNT.get(), 430 INFO_BACKEND_DESC_UNDELETE_COUNT.get(), 431 undeleteCount); 432 } 433 434 if (writabilityMode != null) 435 { 436 addMonitorAttribute(attrs, 437 ATTR_WRITABILITY_MODE, 438 INFO_BACKEND_DISPNAME_WRITABILITY_MODE.get(), 439 INFO_BACKEND_DESC_WRITABILITY_MODE.get(), 440 writabilityMode); 441 } 442 443 if (isPrivate != null) 444 { 445 addMonitorAttribute(attrs, 446 ATTR_IS_PRIVATE, 447 INFO_BACKEND_DISPNAME_IS_PRIVATE.get(), 448 INFO_BACKEND_DESC_IS_PRIVATE.get(), 449 isPrivate); 450 } 451 452 return Collections.unmodifiableMap(attrs); 453 } 454}