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