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