From 4166c20ed1817f2792c6c4a6d12b810c7c256b72 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Sun, 09 Sep 2007 14:48:37 +0000
Subject: [PATCH] - [Issue 1594] entry caches should have monitor information:   implement generic entry cache monitor provider which allows any entry cache implementation current or future   to provide a common or custom set of entry cache state data. update all existing entry cache implementations   so that they provide their common state data to the entry cache monitor provider.

---
 opends/resource/schema/02-config.ldif                                                        |    3 
 opends/src/admin/defn/org/opends/server/admin/std/EntryCacheMonitorProviderConfiguration.xml |   60 ++++++
 opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java                     |   64 +++++-
 opends/src/server/org/opends/server/extensions/DefaultEntryCache.java                        |   15 +
 opends/src/server/org/opends/server/extensions/EntryCacheCommon.java                         |  121 ++++++++++++
 opends/src/server/org/opends/server/extensions/FIFOEntryCache.java                           |   34 +++
 opends/src/server/org/opends/server/monitors/EntryCacheMonitorProvider.java                  |  144 ++++++++++++++++
 opends/src/server/org/opends/server/api/EntryCache.java                                      |   32 +++
 opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java                  |   34 +++
 opends/resource/config/config.ldif                                                           |    8 
 10 files changed, 494 insertions(+), 21 deletions(-)

diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index c04bacf..6b9862b 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -1179,6 +1179,14 @@
 ds-cfg-monitor-provider-class: org.opends.server.monitors.VersionMonitorProvider
 ds-cfg-monitor-provider-enabled: true
 
+dn: cn=Entry Cache,cn=Monitor Providers,cn=config
+objectClass: top
+objectClass: ds-cfg-monitor-provider
+objectClass: ds-cfg-entry-cache-monitor-provider
+cn: Entry Cache
+ds-cfg-monitor-provider-class: org.opends.server.monitors.EntryCacheMonitorProvider
+ds-cfg-monitor-provider-enabled: true
+
 dn: cn=Password Generators,cn=config
 objectClass: top
 objectClass: ds-cfg-branch
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 6723b92..144ad47 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2467,4 +2467,7 @@
   NAME 'ds-cfg-ldif-connection-handler' SUP ds-cfg-connection-handler
   MUST ( ds-cfg-ldif-directory $ ds-cfg-poll-interval )
   X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.173
+  NAME 'ds-cfg-entry-cache-monitor-provider' SUP ds-cfg-monitor-provider
+  STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
 
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/EntryCacheMonitorProviderConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/EntryCacheMonitorProviderConfiguration.xml
new file mode 100644
index 0000000..e3ee763
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/EntryCacheMonitorProviderConfiguration.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! CDDL HEADER START
+!
+! The contents of this file are subject to the terms of the
+! Common Development and Distribution License, Version 1.0 only
+! (the "License").  You may not use this file except in compliance
+! with the License.
+!
+! You can obtain a copy of the license at
+! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+! See the License for the specific language governing permissions
+! and limitations under the License.
+!
+! When distributing Covered Code, include this CDDL HEADER in each
+! file and include the License file at
+! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+! add the following below this CDDL HEADER, with the fields enclosed
+! by brackets "[]" replaced with your own identifying information:
+!      Portions Copyright [yyyy] [name of copyright owner]
+!
+! CDDL HEADER END
+!
+!
+!      Portions Copyright 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+  name="entry-cache-monitor-provider"
+  plural-name="entry-cache-monitor-providers"
+  package="org.opends.server.admin.std"
+  extends="monitor-provider"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+
+  <adm:synopsis>
+    The <adm:user-friendly-name /> exposes monitor information about
+    Directory Server entry cache state.
+  </adm:synopsis>
+
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.173</ldap:oid>
+      <ldap:name>ds-cfg-entry-cache-monitor-provider</ldap:name>
+      <ldap:superior>ds-cfg-monitor-provider</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+
+  <adm:property-override name="monitor-class">
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>
+          org.opends.server.monitors.EntryCacheMonitorProvider
+        </adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+  </adm:property-override>
+
+</adm:managed-object>
diff --git a/opends/src/server/org/opends/server/api/EntryCache.java b/opends/src/server/org/opends/server/api/EntryCache.java
index 09c7d0c..75dae36 100644
--- a/opends/src/server/org/opends/server/api/EntryCache.java
+++ b/opends/src/server/org/opends/server/api/EntryCache.java
@@ -33,6 +33,8 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.locks.Lock;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.config.ConfigException;
@@ -43,6 +45,7 @@
 import org.opends.server.types.LockManager;
 import org.opends.server.types.SearchFilter;
 import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.Attribute;
 import org.opends.server.admin.std.server.EntryCacheCfg;
 import org.opends.server.loggers.debug.DebugTracer;
 import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -105,6 +108,16 @@
   // up.
   private long lockTimeout = LockManager.DEFAULT_TIMEOUT;
 
+  /**
+   * Arbitrary number of cache hits for monitoring.
+   */
+  protected AtomicLong cacheHits = new AtomicLong(0);
+
+  /**
+   * Arbitrary number of cache misses for monitoring.
+   */
+  protected AtomicLong cacheMisses = new AtomicLong(0);
+
 
 
   /**
@@ -239,6 +252,9 @@
                         List<Lock> lockList) {
 
     if (!containsEntry(entryDN)) {
+      // Indicate cache miss.
+      cacheMisses.set(cacheMisses.incrementAndGet());
+
       return null;
     }
 
@@ -391,6 +407,9 @@
     // Translate given backend/entryID pair to entryDN.
     DN entryDN = getEntryDN(backend, entryID);
     if (entryDN == null) {
+      // Indicate cache miss.
+      cacheMisses.set(cacheMisses.incrementAndGet());
+
       return null;
     }
 
@@ -526,6 +545,19 @@
 
 
   /**
+   * Retrieves a set of attributes containing monitor data that should
+   * be returned to the client if the corresponding monitor entry is
+   * requested.
+   *
+   * @return  A set of attributes containing monitor data that should
+   *          be returned to the client if the corresponding monitor
+   *          entry is requested.
+   */
+  public abstract ArrayList<Attribute> getMonitorData();
+
+
+
+  /**
    * Retrieves the maximum length of time in milliseconds to wait for
    * a lock before giving up.
    *
diff --git a/opends/src/server/org/opends/server/extensions/DefaultEntryCache.java b/opends/src/server/org/opends/server/extensions/DefaultEntryCache.java
index 7633e06..4ba492d 100644
--- a/opends/src/server/org/opends/server/extensions/DefaultEntryCache.java
+++ b/opends/src/server/org/opends/server/extensions/DefaultEntryCache.java
@@ -37,6 +37,7 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.EntryCache;
 import org.opends.server.config.ConfigException;
+import org.opends.server.types.Attribute;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
@@ -235,6 +236,18 @@
         );
 
     return changeResult;
-    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public ArrayList<Attribute> getMonitorData()
+  {
+    // This implementation does not store entries,
+    // so there is no monitoring data to provide.
+    return new ArrayList<Attribute>();
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/extensions/EntryCacheCommon.java b/opends/src/server/org/opends/server/extensions/EntryCacheCommon.java
index 52ab40a..eac3bbb 100644
--- a/opends/src/server/org/opends/server/extensions/EntryCacheCommon.java
+++ b/opends/src/server/org/opends/server/extensions/EntryCacheCommon.java
@@ -27,21 +27,24 @@
 package org.opends.server.extensions;
 import org.opends.messages.Message;
 
-import static org.opends.server.loggers.ErrorLogger.logError;
-import org.opends.messages.MessageDescriptor;
-import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
-
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.SortedSet;
 
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
 import org.opends.server.types.DN;
 import org.opends.server.types.DirectoryException;
-
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.SearchFilter;
+import org.opends.messages.MessageDescriptor;
 
+import static org.opends.server.loggers.ErrorLogger.logError;
+import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
 
 /**
  * This class provides some common tools to all entry cache implementations.
@@ -351,5 +354,113 @@
     return errorHandler;
   }
 
+
+  /**
+   * Constructs a set of generic attributes containing entry cache
+   * monitor data. Note that <code>null</code> can be passed in
+   * place of any argument to denote the argument is omitted, such
+   * is when no state data of a given kind is available or can be
+   * provided.
+   *
+   * @param cacheHits      number of cache hits.
+   * @param cacheMisses    number of cache misses.
+   * @param cacheSize      size of the current cache, in bytes.
+   * @param maxCacheSize   maximum allowed cache size, in bytes.
+   * @param cacheCount     number of entries stored in the cache.
+   * @param maxCacheCount  maximum number of cache entries allowed.
+   *
+   * @return  A set of generic attributes containing monitor data.
+   */
+  public static ArrayList<Attribute> getGenericMonitorData(
+    Long cacheHits,
+    Long cacheMisses,
+    Long cacheSize,
+    Long maxCacheSize,
+    Long cacheCount,
+    Long maxCacheCount)
+  {
+    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+    if ((cacheHits != null) && (cacheMisses != null)) {
+      AttributeType hitsAttrType =
+        DirectoryServer.getDefaultAttributeType("entryCacheHits");
+      LinkedHashSet<AttributeValue> hitsValues =
+        new LinkedHashSet<AttributeValue>();
+      hitsValues.add(new AttributeValue(hitsAttrType,
+        cacheHits.toString()));
+      attrs.add(new Attribute(hitsAttrType, "entryCacheHits",
+        hitsValues));
+
+      AttributeType triesAttrType =
+        DirectoryServer.getDefaultAttributeType("entryCacheTries");
+      LinkedHashSet<AttributeValue> triesValues =
+        new LinkedHashSet<AttributeValue>();
+      Long cacheTries = cacheHits + cacheMisses;
+      triesValues.add(new AttributeValue(triesAttrType,
+        cacheTries.toString()));
+      attrs.add(new Attribute(triesAttrType, "entryCacheTries",
+        triesValues));
+
+      AttributeType hitRatioAttrType =
+        DirectoryServer.getDefaultAttributeType("entryCacheHitRatio");
+      LinkedHashSet<AttributeValue> hitRatioValues =
+        new LinkedHashSet<AttributeValue>();
+      Double hitRatioRaw = cacheTries > 0 ?
+        cacheHits.doubleValue() / cacheTries.doubleValue() :
+        cacheHits.doubleValue() / 1;
+      Double hitRatio = hitRatioRaw * 100D;
+      hitRatioValues.add(new AttributeValue(hitRatioAttrType,
+        Long.toString(hitRatio.longValue())));
+      attrs.add(new Attribute(hitRatioAttrType, "entryCacheHitRatio",
+        hitRatioValues));
+    }
+
+    if (cacheSize != null) {
+      AttributeType memoryAttrType =
+        DirectoryServer.getDefaultAttributeType("currentEntryCacheSize");
+      LinkedHashSet<AttributeValue> memoryValues =
+        new LinkedHashSet<AttributeValue>();
+      memoryValues.add(new AttributeValue(memoryAttrType,
+        cacheSize.toString()));
+      attrs.add(new Attribute(memoryAttrType, "currentEntryCacheSize",
+        memoryValues));
+    }
+
+    if (maxCacheSize != null) {
+      AttributeType maxMemoryAttrType =
+        DirectoryServer.getDefaultAttributeType("maxEntryCacheSize");
+      LinkedHashSet<AttributeValue> maxMemoryValues =
+        new LinkedHashSet<AttributeValue>();
+      maxMemoryValues.add(new AttributeValue(maxMemoryAttrType,
+        maxCacheSize.toString()));
+      attrs.add(new Attribute(maxMemoryAttrType, "maxEntryCacheSize",
+        maxMemoryValues));
+    }
+
+    if (cacheCount != null) {
+      AttributeType entriesAttrType =
+        DirectoryServer.getDefaultAttributeType("currentEntryCacheCount");
+      LinkedHashSet<AttributeValue> entriesValues =
+        new LinkedHashSet<AttributeValue>();
+      entriesValues.add(new AttributeValue(entriesAttrType,
+        cacheCount.toString()));
+      attrs.add(new Attribute(entriesAttrType, "currentEntryCacheCount",
+        entriesValues));
+    }
+
+    if (maxCacheCount != null) {
+      AttributeType maxEntriesAttrType =
+        DirectoryServer.getDefaultAttributeType("maxEntryCacheCount");
+      LinkedHashSet<AttributeValue> maxEntriesValues =
+        new LinkedHashSet<AttributeValue>();
+      maxEntriesValues.add(new AttributeValue(maxEntriesAttrType,
+        maxCacheCount.toString()));
+      attrs.add(new Attribute(maxEntriesAttrType, "maxEntryCacheCount",
+        maxEntriesValues));
+    }
+
+    return attrs;
+  }
+
 }
 
diff --git a/opends/src/server/org/opends/server/extensions/FIFOEntryCache.java b/opends/src/server/org/opends/server/extensions/FIFOEntryCache.java
index aff52ec..0a78dcf 100644
--- a/opends/src/server/org/opends/server/extensions/FIFOEntryCache.java
+++ b/opends/src/server/org/opends/server/extensions/FIFOEntryCache.java
@@ -55,6 +55,7 @@
 import org.opends.server.types.Entry;
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.SearchFilter;
+import org.opends.server.types.Attribute;
 import org.opends.server.util.ServerConstants;
 import org.opends.messages.MessageBuilder;
 
@@ -231,10 +232,14 @@
     CacheEntry e = dnMap.get(entryDN);
     if (e == null)
     {
+      // Indicate cache miss.
+      cacheMisses.set(cacheMisses.incrementAndGet());
       return null;
     }
     else
     {
+      // Indicate cache hit.
+      cacheHits.set(cacheHits.incrementAndGet());
       return e.getEntry();
     }
   }
@@ -990,6 +995,35 @@
 
 
   /**
+   * {@inheritDoc}
+   */
+  public ArrayList<Attribute> getMonitorData()
+  {
+    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+    try {
+      attrs = EntryCacheCommon.getGenericMonitorData(
+        new Long(cacheHits.longValue()),
+        new Long(cacheMisses.longValue()),
+        null,
+        new Long(maxAllowedMemory),
+        new Long(dnMap.size()),
+        (((maxEntries != Integer.MAX_VALUE) &&
+          (maxEntries != Long.MAX_VALUE)) ?
+           new Long(maxEntries) : new Long(0))
+        );
+    } catch (Exception e) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+    }
+
+    return attrs;
+  }
+
+
+
+  /**
    * Return a verbose string representation of the current cache maps.
    * This is useful primary for debugging and diagnostic purposes such
    * as in the entry cache unit tests.
diff --git a/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java b/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
index 97442f3..7ae0890 100644
--- a/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
+++ b/opends/src/server/org/opends/server/extensions/FileSystemEntryCache.java
@@ -78,6 +78,7 @@
 import org.opends.server.types.FilePermission;
 import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.OpenDsException;
+import org.opends.server.types.Attribute;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.util.ServerConstants;
 
@@ -626,6 +627,11 @@
       // Use get to generate entry access.
       if (dnMap.get(entryDN) != null) {
         entry = getEntryFromDB(entryDN);
+        // Indicate cache hit.
+        cacheHits.set(cacheHits.incrementAndGet());
+      } else {
+        // Indicate cache miss.
+        cacheMisses.set(cacheMisses.incrementAndGet());
       }
     } finally {
       cacheReadLock.unlock();
@@ -1326,6 +1332,34 @@
   }
 
   /**
+   * {@inheritDoc}
+   */
+  public ArrayList<Attribute> getMonitorData()
+  {
+    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+    try {
+      attrs = EntryCacheCommon.getGenericMonitorData(
+        new Long(cacheHits.longValue()),
+        new Long(cacheMisses.longValue()),
+        new Long(entryCacheEnv.getStats(
+          entryCacheEnvStatsConfig).getTotalLogSize()),
+        new Long(maxAllowedMemory),
+        new Long(dnMap.size()),
+        (((maxEntries.longValue() != Integer.MAX_VALUE) &&
+          (maxEntries.longValue() != Long.MAX_VALUE)) ?
+           new Long(maxEntries.longValue()) : new Long(0))
+        );
+    } catch (Exception e) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+    }
+
+    return attrs;
+  }
+
+  /**
    * Retrieves and decodes the entry with the specified DN from JE backend db.
    *
    * @param  entryDN   The DN of the entry to retrieve.
@@ -1451,15 +1485,15 @@
     }
   }
 
- /**
-  * Checks if the cache home exist and if not tries to recursively create it.
-  * If either is successful adjusts cache home access permissions accordingly
-  * to allow only process owner or the superuser to access JE environment.
-  *
-  * @param  cacheHome  String representation of complete file system path.
-  *
-  * @throws Exception  If failed to establish cache home.
-  */
+  /**
+   * Checks if the cache home exist and if not tries to recursively create it.
+   * If either is successful adjusts cache home access permissions accordingly
+   * to allow only process owner or the superuser to access JE environment.
+   *
+   * @param  cacheHome  String representation of complete file system path.
+   *
+   * @throws Exception  If failed to establish cache home.
+   */
   private void checkAndSetupCacheHome(String cacheHome) throws Exception {
 
     boolean cacheHasHome = false;
@@ -1575,12 +1609,12 @@
     return (verboseString.length() > 0 ? verboseString : null);
   }
 
- /**
-  * This inner class exist solely to override <CODE>removeEldestEntry()</CODE>
-  * method of the LinkedHashMap.
-  *
-  * @see  java.util.LinkedHashMap
-  */
+  /**
+   * This inner class exist solely to override <CODE>removeEldestEntry()</CODE>
+   * method of the LinkedHashMap.
+   *
+   * @see  java.util.LinkedHashMap
+   */
   private class LinkedHashMapRotator<K,V> extends LinkedHashMap<K,V> {
 
     static final long serialVersionUID = 5271482121415968435L;
diff --git a/opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java b/opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java
index ae8e5ba..5ed0888 100644
--- a/opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java
+++ b/opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java
@@ -46,6 +46,7 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.Attribute;
 import org.opends.server.types.CacheEntry;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DebugLogLevel;
@@ -209,6 +210,8 @@
     SoftReference<CacheEntry> ref = dnMap.get(entryDN);
     if (ref == null)
     {
+      // Indicate cache miss.
+      cacheMisses.set(cacheMisses.incrementAndGet());
       return null;
     }
     else
@@ -216,10 +219,14 @@
       CacheEntry cacheEntry = ref.get();
       if (cacheEntry == null)
       {
+        // Indicate cache miss.
+        cacheMisses.set(cacheMisses.incrementAndGet());
         return null;
       }
       else
       {
+        // Indicate cache hit.
+        cacheHits.set(cacheHits.incrementAndGet());
         return cacheEntry.getEntry();
       }
     }
@@ -652,6 +659,33 @@
 
 
   /**
+   * {@inheritDoc}
+   */
+  public ArrayList<Attribute> getMonitorData()
+  {
+    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+    try {
+      attrs = EntryCacheCommon.getGenericMonitorData(
+        new Long(cacheHits.longValue()),
+        new Long(cacheMisses.longValue()),
+        null,
+        null,
+        new Long(dnMap.size()),
+        null
+        );
+    } catch (Exception e) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+    }
+
+    return attrs;
+  }
+
+
+
+  /**
    * Return a verbose string representation of the current cache maps.
    * This is useful primary for debugging and diagnostic purposes such
    * as in the entry cache unit tests.
diff --git a/opends/src/server/org/opends/server/monitors/EntryCacheMonitorProvider.java b/opends/src/server/org/opends/server/monitors/EntryCacheMonitorProvider.java
new file mode 100644
index 0000000..8cba70c
--- /dev/null
+++ b/opends/src/server/org/opends/server/monitors/EntryCacheMonitorProvider.java
@@ -0,0 +1,144 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.monitors;
+
+import java.util.ArrayList;
+
+import org.opends.server.admin.server.ServerManagementContext;
+import org.opends.server.admin.std.server.EntryCacheCfg;
+import org.opends.server.admin.std.server.EntryCacheMonitorProviderCfg;
+import org.opends.server.admin.std.server.RootCfg;
+import org.opends.server.api.EntryCache;
+import org.opends.server.api.MonitorProvider;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.InitializationException;
+
+import static org.opends.server.loggers.debug.DebugLogger.*;
+
+/**
+ * This class defines a Directory Server monitor provider that can be used to
+ * obtain information about the entry cache state. Note that the information
+ * reported is obtained with no locking, so it may not be entirely consistent.
+ */
+public class EntryCacheMonitorProvider
+       extends MonitorProvider<EntryCacheMonitorProviderCfg>
+{
+  /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
+  /**
+   * Creates an instance of this monitor provider.
+   */
+  public EntryCacheMonitorProvider()
+  {
+    super("Entry Cache Monitor Provider");
+
+    // No initialization should be performed here.
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeMonitorProvider(
+                   EntryCacheMonitorProviderCfg configuration)
+         throws ConfigException, InitializationException
+  {
+    // No initialization is required.
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String getMonitorInstanceName()
+  {
+    return "Entry Cache";
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public long getUpdateInterval()
+  {
+    // This monitor does not need to run periodically.
+    return 0;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void updateMonitorData()
+  {
+    // This monitor does not need to run periodically.
+    return;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public ArrayList<Attribute> getMonitorData()
+  {
+    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+    EntryCacheCfg configuration = null;
+
+    // Get the root configuration object.
+    ServerManagementContext managementContext =
+      ServerManagementContext.getInstance();
+    RootCfg rootConfiguration =
+      managementContext.getRootConfiguration();
+
+    // Get the entry cache configuration.
+    try {
+      configuration = rootConfiguration.getEntryCache();
+    } catch (Exception e) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+
+      return attrs;
+    }
+
+    // Get the entry cache.
+    EntryCache<? extends EntryCacheCfg> cache =
+      (EntryCache<? extends EntryCacheCfg>)
+       DirectoryServer.getEntryCache();
+
+    if ((cache != null) &&
+        (configuration != null) &&
+         configuration.isEnabled()) {
+      // Get data from the cache.
+      attrs = cache.getMonitorData();
+    }
+
+    return attrs;
+  }
+}

--
Gitblit v1.10.0