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.LinkedHashMap;
042import java.util.Map;
043
044import com.unboundid.ldap.sdk.Entry;
045import com.unboundid.util.NotMutable;
046import com.unboundid.util.NotNull;
047import com.unboundid.util.Nullable;
048import com.unboundid.util.StaticUtils;
049import com.unboundid.util.ThreadSafety;
050import com.unboundid.util.ThreadSafetyLevel;
051
052import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
053
054
055
056/**
057 * This class defines a monitor entry that provides general information about
058 * the state of the Directory Server entry cache.
059 * <BR>
060 * <BLOCKQUOTE>
061 *   <B>NOTE:</B>  This class, and other classes within the
062 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
063 *   supported for use against Ping Identity, UnboundID, and
064 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
065 *   for proprietary functionality or for external specifications that are not
066 *   considered stable or mature enough to be guaranteed to work in an
067 *   interoperable way with other types of LDAP servers.
068 * </BLOCKQUOTE>
069 * <BR>
070 * The information that may be available in the entry cache monitor entry
071 * includes:
072 * <UL>
073 *   <LI>The number of cache tries, which are attempts to retrieve entries from
074 *       the cache.</LI>
075 *   <LI>The number of cache hits, which are successful attempts to retrieve an
076 *       entry from the cache.</LI>
077 *   <LI>The number of cache misses, which are unsuccessful attempts to retrieve
078 *       an entry from the cache.</LI>
079 *   <LI>The cache hit ratio, which is the ratio of the time that a cache try is
080 *       successful.</LI>
081 *   <LI>The number of entries currently held in the cache.</LI>
082 *   <LI>The maximum number of entries that may be held in the cache.</LI>
083 *   <LI>The approximate current amount of memory consumed by the cache.</LI>
084 *   <LI>The maximum amount of memory that may be consumed by the cache.</LI>
085 * </UL>
086 * The server should present at most one client connection monitor entry.  It
087 * can be retrieved using the
088 * {@link MonitorManager#getEntryCacheMonitorEntry} method.  This entry provides
089 * specific methods for accessing information about the entry cache (e.g., the
090 * {@link EntryCacheMonitorEntry#getCurrentCount} method can be used
091 * to retrieve the number of entries currently in the cache).  Alternately, this
092 * information may be accessed using the generic API.  See the
093 * {@link MonitorManager} class documentation for an example that demonstrates
094 * the use of the generic API for accessing monitor data.
095 */
096@NotMutable()
097@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
098public final class EntryCacheMonitorEntry
099       extends MonitorEntry
100{
101  /**
102   * The structural object class used in entry cache monitor entries.
103   */
104  @NotNull static final String ENTRY_CACHE_MONITOR_OC =
105       "ds-entry-cache-monitor-entry";
106
107
108
109  /**
110   * The name of the attribute that provides the number of entries currently
111   * held in the cache.
112   */
113  @NotNull private static final String ATTR_CURRENT_COUNT =
114       "currentEntryCacheCount";
115
116
117
118  /**
119   * The name of the attribute that provides the current entry cache size in
120   * bytes.
121   */
122  @NotNull private static final String ATTR_CURRENT_SIZE =
123       "currentEntryCacheSize";
124
125
126
127  /**
128   * The name of the attribute that provides the entry cache hit ratio.
129   */
130  @NotNull private static final String ATTR_HIT_RATIO = "entryCacheHitRatio";
131
132
133
134  /**
135   * The name of the attribute that provides the number of cache hits.
136   */
137  @NotNull private static final String ATTR_HITS = "entryCacheHits";
138
139
140
141  /**
142   * The name of the attribute that provides the maximum number of entries that
143   * may be held in the cache.
144   */
145  @NotNull private static final String ATTR_MAX_COUNT = "maxEntryCacheCount";
146
147
148
149  /**
150   * The name of the attribute that provides the maximum entry cache size in
151   * bytes.
152   */
153  @NotNull private static final String ATTR_MAX_SIZE = "maxEntryCacheSize";
154
155
156
157  /**
158   * The name of the attribute that provides the number of cache tries.
159   */
160  @NotNull private static final String ATTR_TRIES = "entryCacheTries";
161
162
163
164  /**
165   * The serial version UID for this serializable class.
166   */
167  private static final long serialVersionUID = 2468261007112908567L;
168
169
170
171  // The hit ratio.
172  @Nullable private final Double hitRatio;
173
174  // The number of cache hits.
175  @Nullable private final Long cacheHits;
176
177  // The number of cache misses.
178  @Nullable private final Long cacheMisses;
179
180  // The number of cache tries.
181  @Nullable private final Long cacheTries;
182
183  // The current number of entries in the cache.
184  @Nullable private final Long currentCount;
185
186  // The current size of the cache.
187  @Nullable private final Long currentSize;
188
189  // The maximum number of entries in the cache.
190  @Nullable private final Long maxCount;
191
192  // The maximum size of the cache.
193  @Nullable private final Long maxSize;
194
195
196
197  /**
198   * Creates a new entry cache monitor entry from the provided entry.
199   *
200   * @param  entry  The entry to be parsed as an entry cache monitor entry.  It
201   *                must not be {@code null}.
202   */
203  public EntryCacheMonitorEntry(@NotNull final Entry entry)
204  {
205    super(entry);
206
207    cacheHits    = getLong(ATTR_HITS);
208    cacheTries   = getLong(ATTR_TRIES);
209    hitRatio     = getDouble(ATTR_HIT_RATIO);
210    currentCount = getLong(ATTR_CURRENT_COUNT);
211    maxCount     = getLong(ATTR_MAX_COUNT);
212    currentSize  = getLong(ATTR_CURRENT_SIZE);
213    maxSize      = getLong(ATTR_MAX_SIZE);
214
215    if ((cacheHits == null) || (cacheTries == null))
216    {
217      cacheMisses = null;
218    }
219    else
220    {
221      cacheMisses = cacheTries - cacheHits;
222    }
223  }
224
225
226
227  /**
228   * Retrieves the number of attempts to find an entry in the cache.
229   *
230   * @return  The number of attempts to find an entry in the cache, or
231   *          {@code null} if it was not included in the monitor entry.
232   */
233  @Nullable()
234  public Long getCacheTries()
235  {
236    return cacheTries;
237  }
238
239
240
241  /**
242   * Retrieves the number of attempts to find an entry in the cache in which the
243   * entry was found.
244   *
245   * @return  The number of attempts to find an entry in the cache in which the
246   *          entry was found, or {@code null} if it was not included in the
247   *          monitor entry.
248   */
249  @Nullable()
250  public Long getCacheHits()
251  {
252    return cacheHits;
253  }
254
255
256
257  /**
258   * Retrieves the number of attempts to find an entry in the cache in which the
259   * entry was not found.
260   *
261   * @return  The number of attempts to find an entry in the cache in which the
262   *          entry was not found, or {@code null} if it was not included in the
263   *          monitor entry.
264   */
265  @Nullable()
266  public Long getCacheMisses()
267  {
268    return cacheMisses;
269  }
270
271
272
273  /**
274   * Retrieves the ratio of the time a requested entry was found in the cache.
275   *
276   * @return  The ratio of the time a requested entry was found in the cache, or
277   *          {@code null} if it was not included in the monitor entry.
278   */
279  @Nullable()
280  public Double getCacheHitRatio()
281  {
282    return hitRatio;
283  }
284
285
286
287  /**
288   * Retrieves the number of entries currently held in the entry cache.
289   *
290   * @return  The number of entries currently held in the entry cache, or
291   *          {@code null} if it was not included in the monitor entry.
292   */
293  @Nullable()
294  public Long getCurrentCount()
295  {
296    return currentCount;
297  }
298
299
300
301  /**
302   * Retrieves the maximum number of entries that may be held in the entry
303   * cache.
304   *
305   * @return  The maximum number of entries that may be held in the entry cache,
306   *          or {@code null} if it was not included in the monitor entry.
307   */
308  @Nullable()
309  public Long getMaxCount()
310  {
311    return maxCount;
312  }
313
314
315
316  /**
317   * Retrieves the current amount of memory (in bytes) consumed by the entry
318   * cache.
319   *
320   * @return  The current amount of memory (in bytes) consumed by the entry
321   *          cache, or {@code null} if it was not included in the monitor
322   *          entry.
323   */
324  @Nullable()
325  public Long getCurrentCacheSize()
326  {
327    return currentSize;
328  }
329
330
331
332  /**
333   * Retrieves the maximum amount of memory (in bytes) that may be consumed by
334   * the entry cache.
335   *
336   * @return  The maximum amount of memory (in bytes) that may be consumed by
337   *          the entry cache, or {@code null} if it was not included in the
338   *          monitor entry.
339   */
340  @Nullable()
341  public Long getMaxCacheSize()
342  {
343    return maxSize;
344  }
345
346
347
348  /**
349   * {@inheritDoc}
350   */
351  @Override()
352  @NotNull()
353  public String getMonitorDisplayName()
354  {
355    return INFO_ENTRY_CACHE_MONITOR_DISPNAME.get();
356  }
357
358
359
360  /**
361   * {@inheritDoc}
362   */
363  @Override()
364  @NotNull()
365  public String getMonitorDescription()
366  {
367    return INFO_ENTRY_CACHE_MONITOR_DESC.get();
368  }
369
370
371
372  /**
373   * {@inheritDoc}
374   */
375  @Override()
376  @NotNull()
377  public Map<String,MonitorAttribute> getMonitorAttributes()
378  {
379    final LinkedHashMap<String,MonitorAttribute> attrs =
380         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
381
382    if (cacheTries != null)
383    {
384      addMonitorAttribute(attrs,
385           ATTR_TRIES,
386           INFO_ENTRY_CACHE_DISPNAME_TRIES.get(),
387           INFO_ENTRY_CACHE_DESC_TRIES.get(),
388           cacheTries);
389    }
390
391    if (cacheHits != null)
392    {
393      addMonitorAttribute(attrs,
394           ATTR_HITS,
395           INFO_ENTRY_CACHE_DISPNAME_HITS.get(),
396           INFO_ENTRY_CACHE_DESC_HITS.get(),
397           cacheHits);
398    }
399
400    if (cacheMisses != null)
401    {
402      addMonitorAttribute(attrs,
403           "entryCacheMisses",
404           INFO_ENTRY_CACHE_DISPNAME_MISSES.get(),
405           INFO_ENTRY_CACHE_DESC_MISSES.get(),
406           cacheMisses);
407    }
408
409    if (hitRatio != null)
410    {
411      addMonitorAttribute(attrs,
412           ATTR_HIT_RATIO,
413           INFO_ENTRY_CACHE_DISPNAME_HIT_RATIO.get(),
414           INFO_ENTRY_CACHE_DESC_HIT_RATIO.get(),
415           hitRatio);
416    }
417
418    if (currentCount != null)
419    {
420      addMonitorAttribute(attrs,
421           ATTR_CURRENT_COUNT,
422           INFO_ENTRY_CACHE_DISPNAME_CURRENT_COUNT.get(),
423           INFO_ENTRY_CACHE_DESC_CURRENT_COUNT.get(),
424           currentCount);
425    }
426
427    if (maxCount != null)
428    {
429      addMonitorAttribute(attrs,
430           ATTR_MAX_COUNT,
431           INFO_ENTRY_CACHE_DISPNAME_MAX_COUNT.get(),
432           INFO_ENTRY_CACHE_DESC_MAX_COUNT.get(),
433           maxCount);
434    }
435
436    if (currentSize != null)
437    {
438      addMonitorAttribute(attrs,
439           ATTR_CURRENT_SIZE,
440           INFO_ENTRY_CACHE_DISPNAME_CURRENT_SIZE.get(),
441           INFO_ENTRY_CACHE_DESC_CURRENT_SIZE.get(),
442           currentSize);
443    }
444
445    if (maxSize != null)
446    {
447      addMonitorAttribute(attrs,
448           ATTR_MAX_SIZE,
449           INFO_ENTRY_CACHE_DISPNAME_MAX_SIZE.get(),
450           INFO_ENTRY_CACHE_DESC_MAX_SIZE.get(),
451           maxSize);
452    }
453
454    return Collections.unmodifiableMap(attrs);
455  }
456}