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