From a743f8cd823be717769cb97ad294b521a6ac8042 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 17 Dec 2014 22:59:42 +0000
Subject: [PATCH] OPENDJ-1602 (CR-5566) New pluggable storage based backend

---
 /dev/null                                                                                                                    |  726 ------------------------------------------
 opendj-sdk/opendj3-server-dev/resource/config/config.ldif                                                                    |    9 
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java                               |   57 ---
 opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java |   25 
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java                                         |   43 --
 opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/DefaultEntryCacheTestCase.java |   59 ---
 opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/BackendImpl.java                                     |   53 ---
 7 files changed, 12 insertions(+), 960 deletions(-)

diff --git a/opendj-sdk/opendj3-server-dev/resource/config/config.ldif b/opendj-sdk/opendj3-server-dev/resource/config/config.ldif
index dcabd11..c2d3f4dc 100644
--- a/opendj-sdk/opendj3-server-dev/resource/config/config.ldif
+++ b/opendj-sdk/opendj3-server-dev/resource/config/config.ldif
@@ -557,15 +557,6 @@
 ds-cfg-cache-level: 2
 ds-cfg-java-class: org.opends.server.extensions.SoftReferenceEntryCache
 
-dn: cn=File System,cn=Entry Caches,cn=config
-objectClass: top
-objectClass: ds-cfg-entry-cache
-objectClass: ds-cfg-file-system-entry-cache
-cn: File System
-ds-cfg-enabled: false
-ds-cfg-cache-level: 3
-ds-cfg-java-class: org.opends.server.extensions.FileSystemEntryCache
-
 dn: cn=Extended Operations,cn=config
 objectClass: top
 objectClass: ds-cfg-branch
diff --git a/opendj-sdk/opendj3-server-dev/src/admin/defn/org/opends/server/admin/std/FileSystemEntryCacheConfiguration.xml b/opendj-sdk/opendj3-server-dev/src/admin/defn/org/opends/server/admin/std/FileSystemEntryCacheConfiguration.xml
deleted file mode 100644
index 13de250..0000000
--- a/opendj-sdk/opendj3-server-dev/src/admin/defn/org/opends/server/admin/std/FileSystemEntryCacheConfiguration.xml
+++ /dev/null
@@ -1,303 +0,0 @@
-<?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 legal-notices/CDDLv1_0.txt
-  ! or http://forgerock.org/license/CDDLv1.0.html.
-  ! 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 legal-notices/CDDLv1_0.txt.
-  ! 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
-  !
-  !
-  !      Copyright 2007-2008 Sun Microsystems, Inc.
-  !      Portions Copyright 2011 ForgeRock AS
-  ! -->
-<adm:managed-object name="file-system-entry-cache"
-  plural-name="file-system-entry-caches"
-  package="org.opends.server.admin.std" extends="entry-cache"
-  xmlns:adm="http://www.opends.org/admin"
-  xmlns:ldap="http://www.opends.org/admin-ldap">
-  <adm:synopsis>
-    The
-    <adm:user-friendly-name />
-    is an entry cache implementation which uses a JE database to keep
-    track of the entries.
-  </adm:synopsis>
-  <adm:description>
-    For best performance, the JE database should reside in a memory
-    based file system although any file system will do for this cache
-    to function. Entries are maintained either by FIFO (default) or LRU-based
-    (configurable) list implementation. Cache sizing is based on
-    the size of free space available in the file system, such that if
-    enough memory is free, then adding an entry to the cache will not
-    require purging. If more than the specified size of the file
-    system available space is already consumed, then one or more entries
-    need to be removed in order to make room for a new entry. It is
-    also possible to configure a maximum number of entries for the cache.
-    If this is specified, then the number of entries are not allowed
-    to exceed this value, but it may not be possible to hold this many
-    entries if the available memory fills up first. Other configurable
-    parameters for this cache include the maximum length of time to block
-    while waiting to acquire a lock, and a set of filters that may be
-    used to define criteria for determining which entries are stored in
-    the cache. If a set of filters are provided then an entry must match
-    at least one of them in order to be stored in the cache.
-    JE environment cache size can also be configured either as a percentage
-    of the free memory available in the JVM, or as an absolute size in
-    bytes. This cache has a persistence property which, if enabled,
-    allows for the contents of the cache to persist across server or
-    cache restarts.
-  </adm:description>
-  <adm:profile name="ldap">
-    <ldap:object-class>
-      <ldap:name>ds-cfg-file-system-entry-cache</ldap:name>
-      <ldap:superior>ds-cfg-entry-cache</ldap:superior>
-    </ldap:object-class>
-  </adm:profile>
-  <adm:property name="lock-timeout" advanced="true">
-    <adm:synopsis>
-      The length of time to wait while attempting to acquire a read or
-      write lock.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>2000.0ms</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:duration base-unit="ms" allow-unlimited="true" />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-lock-timeout</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="max-memory-size">
-    <adm:synopsis>
-      The maximum size of the entry cache in bytes.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>0b</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:size />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-max-memory-size</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="max-entries">
-    <adm:synopsis>
-      The maximum number of entries allowed in the cache.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>2147483647</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:integer lower-limit="0" />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-max-entries</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="cache-type">
-    <adm:synopsis>
-      Specifies the policy which should be used for purging entries from
-      the cache.
-    </adm:synopsis>
-    <adm:requires-admin-action>
-      <adm:component-restart />
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>fifo</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:enumeration>
-        <adm:value name="fifo">
-          <adm:synopsis>FIFO based entry cache.</adm:synopsis>
-        </adm:value>
-        <adm:value name="lru">
-          <adm:synopsis>LRU based entry cache.</adm:synopsis>
-        </adm:value>
-      </adm:enumeration>
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-cache-type</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="cache-directory">
-    <adm:synopsis>
-      Specifies the directory in which the JE environment should store
-      the cache.
-    </adm:synopsis>
-    <adm:requires-admin-action>
-      <adm:component-restart />
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>/tmp/OpenDJ.FSCache</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:string />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-cache-directory</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="persistent-cache">
-    <adm:synopsis>
-      Specifies whether the cache should persist across restarts.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>false</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:boolean />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-persistent-cache</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="compact-encoding">
-    <adm:synopsis>
-      Indicates whether the cache should use a compact form when
-      encoding cache entries by compressing the attribute descriptions
-      and object class sets.
-    </adm:synopsis>
-    <adm:description>
-      Note that compression does not preserve user-supplied
-      capitalization in the object class and attribute type names.
-    </adm:description>
-    <adm:requires-admin-action>
-      <adm:none>
-        <adm:synopsis>
-          Changing this property only affects the encoding of the
-          cache entries put in the cache after the change is made. It
-          will not be retroactively applied to existing cache entries.
-        </adm:synopsis>
-      </adm:none>
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>true</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:boolean />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-compact-encoding</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="db-cache-percent">
-    <adm:synopsis>
-      Specifies the maximum memory usage for the internal JE cache as a percentage
-      of the total JVM memory.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>1</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:integer lower-limit="0" upper-limit="90" />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-db-cache-percent</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="db-cache-size">
-    <adm:synopsis>
-      Specifies the maximum JVM memory usage in bytes for the internal JE cache.
-    </adm:synopsis>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>0b</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:size />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-db-cache-size</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property name="je-property" multi-valued="true"
-    advanced="true">
-    <adm:synopsis>
-      Specifies the environment properties for the Berkeley DB Java
-      Edition database providing the backend for this entry cache.
-    </adm:synopsis>
-    <adm:description>
-      Any Berkeley DB Java Edition property can be specified using the
-      following form: property-name=property-value. Refer to the
-      <adm:product-name /> documentation for further information on related
-      properties, their implications and range values. The definitive
-      identification of all the property parameters available in the
-      example.properties file in the Berkeley DB Java Edition distribution.
-    </adm:description>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>je.env.isLocking=false</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:string />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-je-property</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
-  <adm:property-reference name="include-filter" />
-  <adm:property-reference name="exclude-filter" />
-  <adm:property-override name="java-class" advanced="true">
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>
-          org.opends.server.extensions.FileSystemEntryCache
-        </adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-  </adm:property-override>
-</adm:managed-object>
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/BackendImpl.java
index 556d614..544ae50 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -27,16 +27,12 @@
 package org.opends.server.backends.jeb;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
-import java.util.zip.Adler32;
-import java.util.zip.CheckedInputStream;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
@@ -153,50 +149,6 @@
     }
   }
 
-  /**
-   * This method will attempt to checksum the current JE db environment by
-   * computing the Adler-32 checksum on the latest JE log file available.
-   *
-   * @return  The checksum of JE db environment or zero if checksum failed.
-   */
-  private long checksumDbEnv() {
-
-    File parentDirectory = getFileForPath(cfg.getDBDirectory());
-    File backendDirectory = new File(parentDirectory, cfg.getBackendId());
-
-    List<File> jdbFiles = new ArrayList<File>();
-    if(backendDirectory.isDirectory())
-    {
-      jdbFiles =
-          Arrays.asList(backendDirectory.listFiles(new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-              return name.endsWith(".jdb");
-            }
-          }));
-    }
-
-    if ( !jdbFiles.isEmpty() ) {
-      Collections.sort(jdbFiles, Collections.reverseOrder());
-      FileInputStream fis = null;
-      try {
-        fis = new FileInputStream(jdbFiles.get(0).toString());
-        CheckedInputStream cis = new CheckedInputStream(fis, new Adler32());
-        byte[] tempBuf = new byte[8192];
-        while (cis.read(tempBuf) >= 0) {
-        }
-
-        return cis.getChecksum().getValue();
-      } catch (Exception e) {
-        logger.traceException(e);
-      } finally {
-        close(fis);
-      }
-    }
-
-    return 0;
-  }
-
   /** {@inheritDoc} */
   @Override
   public void configureBackend(LocalDBBackendCfg cfg) throws ConfigException
@@ -212,9 +164,6 @@
   public void initializeBackend()
       throws ConfigException, InitializationException
   {
-    // Checksum this db environment and register its offline state id/checksum.
-    DirectoryServer.registerOfflineBackendStateID(getBackendID(), checksumDbEnv());
-
     if (mustOpenRootContainer())
     {
       rootContainer = initializeRootContainer(parseConfigEntry(cfg));
@@ -310,8 +259,6 @@
       logger.error(ERR_JEB_DATABASE_EXCEPTION, e.getMessage());
     }
 
-    // Checksum this db environment and register its offline state id/checksum.
-    DirectoryServer.registerOfflineBackendStateID(getBackendID(), checksumDbEnv());
     DirectoryServer.deregisterAlertGenerator(this);
 
     // Make sure the thread counts are zero for next initialization.
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
index 585d715..1a54c7c 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
@@ -27,15 +27,11 @@
 package org.opends.server.backends.pluggable;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
-import java.util.zip.Adler32;
-import java.util.zip.CheckedInputStream;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
@@ -67,8 +63,8 @@
  * This is an implementation of a Directory Server Backend which stores entries
  * locally in a Berkeley DB JE database.
  */
-public class BackendImpl extends Backend<LocalDBBackendCfg>
-    implements ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator,
+public class BackendImpl extends Backend<LocalDBBackendCfg> implements
+    ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator,
     DiskSpaceMonitorHandler
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
@@ -130,50 +126,6 @@
     }
   }
 
-  /**
-   * This method will attempt to checksum the current JE db environment by
-   * computing the Adler-32 checksum on the latest JE log file available.
-   *
-   * @return  The checksum of JE db environment or zero if checksum failed.
-   */
-  private long checksumDbEnv() {
-
-    File parentDirectory = getFileForPath(cfg.getDBDirectory());
-    File backendDirectory = new File(parentDirectory, cfg.getBackendId());
-
-    List<File> jdbFiles = new ArrayList<File>();
-    if(backendDirectory.isDirectory())
-    {
-      jdbFiles =
-          Arrays.asList(backendDirectory.listFiles(new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-              return name.endsWith(".jdb");
-            }
-          }));
-    }
-
-    if ( !jdbFiles.isEmpty() ) {
-      Collections.sort(jdbFiles, Collections.reverseOrder());
-      FileInputStream fis = null;
-      try {
-        fis = new FileInputStream(jdbFiles.get(0).toString());
-        CheckedInputStream cis = new CheckedInputStream(fis, new Adler32());
-        byte[] tempBuf = new byte[8192];
-        while (cis.read(tempBuf) >= 0) {
-        }
-
-        return cis.getChecksum().getValue();
-      } catch (Exception e) {
-        logger.traceException(e);
-      } finally {
-        close(fis);
-      }
-    }
-
-    return 0;
-  }
-
   /** {@inheritDoc} */
   @Override
   public void configureBackend(LocalDBBackendCfg cfg) throws ConfigException
@@ -189,9 +141,6 @@
   public void initializeBackend()
       throws ConfigException, InitializationException
   {
-    // Checksum this db environment and register its offline state id/checksum.
-    DirectoryServer.registerOfflineBackendStateID(getBackendID(), checksumDbEnv());
-
     if (mustOpenRootContainer())
     {
       rootContainer = initializeRootContainer();
@@ -285,8 +234,6 @@
       logger.error(ERR_JEB_DATABASE_EXCEPTION, e.getMessage());
     }
 
-    // Checksum this db environment and register its offline state id/checksum.
-    DirectoryServer.registerOfflineBackendStateID(getBackendID(), checksumDbEnv());
     DirectoryServer.deregisterAlertGenerator(this);
 
     // Make sure the thread counts are zero for next initialization.
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java
index 4daaa84..7588f22 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java
@@ -775,13 +775,6 @@
   /** The set of backends registered with the server. */
   private TreeMap<String, Backend<?>> backends;
 
-  /**
-   * The mapping between backends and their unique identifiers for their offline
-   * state, representing either checksum or other unique value to be used for
-   * detecting any offline modifications to a given backend.
-   */
-  private ConcurrentMap<String, Long> offlineBackendsStateIDs;
-
   /** The set of supported controls registered with the Directory Server. */
   private final TreeSet<String> supportedControls = new TreeSet<String>(Arrays.asList(
       OID_LDAP_ASSERTION,
@@ -1088,8 +1081,6 @@
            new ConcurrentHashMap<String,
                     MonitorProvider<? extends MonitorProviderCfg>>();
       directoryServer.backends = new TreeMap<String, Backend<?>>();
-      directoryServer.offlineBackendsStateIDs =
-           new ConcurrentHashMap<String,Long>();
       directoryServer.backendInitializationListeners =
            new CopyOnWriteArraySet<BackendInitializationListener>();
       directoryServer.baseDnRegistry = new BaseDnRegistry();
@@ -1555,9 +1546,6 @@
       // If not then stick with default entry cache initialized earlier.
       entryCacheConfigManager.initializeEntryCache();
 
-      // Reset the map as we can no longer guarantee offline state.
-      directoryServer.offlineBackendsStateIDs.clear();
-
       initializeExtendedOperations();
       initializeSASLMechanisms();
 
@@ -5191,37 +5179,6 @@
 
 
   /**
-   * This method returns a map that contains a unique offline state id,
-   * such as checksum, for every server backend that has registered one.
-   *
-   * @return  <CODE>Map</CODE> backend to checksum map for offline state.
-   */
-  public static Map<String,Long> getOfflineBackendsStateIDs() {
-    return Collections.unmodifiableMap(directoryServer.offlineBackendsStateIDs);
-  }
-
-
-
-  /**
-   * This method allows any server backend to register its unique offline
-   * state, such as checksum, in a global map other server components can
-   * access to determine if any changes were made to given backend while
-   * offline.
-   *
-   * @param  backend  As returned by <CODE>getBackendID()</CODE> method.
-   *
-   * @param  id       Unique offline state identifier such as checksum.
-   */
-  public static void registerOfflineBackendStateID(String backend, long id) {
-    // Zero means failed checksum so just skip it.
-    if (id != 0) {
-      directoryServer.offlineBackendsStateIDs.put(backend, id);
-    }
-  }
-
-
-
-  /**
    * Retrieves the entire set of base DNs registered with the Directory Server,
    * mapped from the base DN to the backend responsible for that base DN.  The
    * same backend may be present multiple times, mapped from different base DNs.
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCache.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCache.java
deleted file mode 100644
index 41be44e..0000000
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCache.java
+++ /dev/null
@@ -1,1539 +0,0 @@
-/*
- * 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 legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * 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 legal-notices/CDDLv1_0.txt.
- * 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
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
- */
-package org.opends.server.extensions;
-
-import java.io.File;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import com.sleepycat.bind.EntryBinding;
-import com.sleepycat.bind.serial.SerialBinding;
-import com.sleepycat.bind.serial.StoredClassCatalog;
-import com.sleepycat.je.Environment;
-import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.je.EnvironmentMutableConfig;
-import com.sleepycat.je.Database;
-import com.sleepycat.je.DatabaseConfig;
-import com.sleepycat.je.DatabaseEntry;
-import com.sleepycat.je.DatabaseNotFoundException;
-import com.sleepycat.je.LockMode;
-import com.sleepycat.je.OperationStatus;
-import com.sleepycat.je.StatsConfig;
-import com.sleepycat.je.config.ConfigParam;
-import com.sleepycat.je.config.EnvironmentParams;
-
-import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.i18n.slf4j.LocalizedLogger;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.ByteStringBuilder;
-import org.forgerock.util.Utils;
-import org.opends.server.admin.server.ConfigurationChangeListener;
-import org.opends.server.admin.server.ServerManagementContext;
-import org.opends.server.admin.std.server.EntryCacheCfg;
-import org.opends.server.admin.std.server.FileSystemEntryCacheCfg;
-import org.opends.server.admin.std.server.RootCfg;
-import org.opends.server.api.Backend;
-import org.opends.server.api.EntryCache;
-import org.opends.server.backends.jeb.ConfigurableEnvironment;
-import org.forgerock.opendj.config.server.ConfigException;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.*;
-import org.forgerock.opendj.ldap.ResultCode;
-import org.opends.server.util.ServerConstants;
-
-import static org.opends.messages.ConfigMessages.*;
-import static org.opends.messages.ExtensionMessages.*;
-import static org.opends.server.config.ConfigConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-
-/**
- * This class defines a Directory Server entry cache that uses JE database to
- * keep track of the entries. Intended use is when JE database resides in the
- * memory based file system which has obvious performance benefits, although
- * any file system will do for this cache to function. Entries are maintained
- * either by FIFO (default) or LRU (configurable) based list implementation.
- * <BR><BR>
- * Cache sizing is based on the size of free space available in the file
- * system, such that if enough memory is free, then adding an entry to the
- * cache will not require purging, but if more than a specified size of the
- * file system available space is already consumed, then one or more entries
- * will need to be removed in order to make room for a new entry. It is also
- * possible to configure a maximum number of entries for the cache. If this
- * is specified, then the number of entries will not be allowed to exceed
- * this value, but it may not be possible to hold this many entries if the
- * available memory fills up first.
- * <BR><BR>
- * Other configurable parameters for this cache include the maximum length of
- * time to block while waiting to acquire a lock, and a set of filters that may
- * be used to define criteria for determining which entries are stored in the
- * cache.  If a filter list is provided, then only entries matching at least
- * one of the given filters will be stored in the cache.
- * <BR><BR>
- * JE environment cache size can also be configured either as percentage of
- * the free memory available in the JVM or as explicit size in bytes.
- * <BR><BR>
- * This cache has a persistence property which, if enabled, allows for the
- * contents of the cache to stay persistent across server or cache restarts.
- */
-public class FileSystemEntryCache
-        extends EntryCache <FileSystemEntryCacheCfg>
-        implements ConfigurationChangeListener <FileSystemEntryCacheCfg> {
-  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
-
-  // Permissions for cache db environment.
-  private static final FilePermission CACHE_HOME_PERMISSIONS =
-      new FilePermission(0700);
-
-  // The maximum amount of space in bytes that can be consumed in the filesystem
-  // before we need to start purging entries.
-  private long maxAllowedMemory;
-
-  // The maximum number of entries that may be held in the cache.
-  // Atomic for additional safety and in case we decide to push
-  // some locks further down later. Does not inhere in additional
-  // overhead, via blocking on synchronization primitive, on most
-  // modern platforms being implemented via cpu instruction set.
-  private AtomicLong maxEntries;
-
-  // The entry cache home folder to host db environment.
-  private String cacheHome;
-
-  // The type of this cache.
-  // It can be either FIFO (default) or LRU (configurable).
-  private String cacheType;
-
-  // This regulates whether we persist the cache across restarts or not.
-  private boolean persistentCache;
-
-  // The lock used to provide threadsafe access when changing the contents
-  // of the cache maps.
-  private ReentrantReadWriteLock cacheLock;
-  private Lock cacheReadLock;
-  private Lock cacheWriteLock;
-
-  // Entry Cache Index.
-  FileSystemEntryCacheIndex entryCacheIndex;
-
-  // Access order for this cache. FIFO by default.
-  boolean accessOrder = false;
-
-  // JE environment and database related fields for this cache.
-  private Environment entryCacheEnv;
-  private EnvironmentConfig entryCacheEnvConfig;
-  private EnvironmentMutableConfig entryCacheEnvMutableConfig;
-  private DatabaseConfig entryCacheDBConfig;
-
-  // Statistics retrieval operation config for this JE environment.
-  private StatsConfig entryCacheEnvStatsConfig = new StatsConfig();
-
-  // The main entry cache database.
-  private Database entryCacheDB;
-
-  // Class database, catalog and binding for serialization.
-  private Database entryCacheClassDB;
-  private StoredClassCatalog classCatalog;
-  private EntryBinding<FileSystemEntryCacheIndex> entryCacheDataBinding;
-
-  // JE naming constants.
-  private static final String ENTRYCACHEDBNAME = "EntryCacheDB";
-  private static final String INDEXCLASSDBNAME = "IndexClassDB";
-  private static final String INDEXKEY = "EntryCacheIndex";
-
-  // The configuration to use when encoding entries in the database.
-  private EntryEncodeConfig encodeConfig =
-    new EntryEncodeConfig(true, true, true);
-
-  // JE native properties to configuration attributes map.
-  private HashMap<String, String> configAttrMap =
-    new HashMap<String, String>();
-
-  // Currently registered configuration object.
-  private FileSystemEntryCacheCfg registeredConfiguration;
-
-  // The maximum length of time to try to obtain a lock before giving
-  // up.
-  private long lockTimeout = LockManager.DEFAULT_TIMEOUT;
-
-  /**
-   * Creates a new instance of this entry cache.
-   */
-  public FileSystemEntryCache() {
-    super();
-
-    // Register all JE native properties that map to
-    // corresponding config attributes.
-    configAttrMap.put("je.maxMemoryPercent",
-      ConfigurableEnvironment.ATTR_DATABASE_CACHE_PERCENT);
-    configAttrMap.put("je.maxMemory",
-      ConfigurableEnvironment.ATTR_DATABASE_CACHE_SIZE);
-
-    // All initialization should be performed in the initializeEntryCache.
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void initializeEntryCache(FileSystemEntryCacheCfg configuration)
-          throws ConfigException, InitializationException {
-
-    registeredConfiguration = configuration;
-    configuration.addFileSystemChangeListener (this);
-
-    // Read and apply configuration.
-    boolean applyChanges = true;
-    ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>();
-    EntryCacheCommon.ConfigErrorHandler errorHandler =
-      EntryCacheCommon.getConfigErrorHandler (
-          EntryCacheCommon.ConfigPhase.PHASE_INIT, null, errorMessages
-          );
-    if (!processEntryCacheConfig(configuration, applyChanges, errorHandler)) {
-      String buffer = Utils.joinAsString(".  ", errorMessages);
-      throw new ConfigException(ERR_FSCACHE_CANNOT_INITIALIZE.get(buffer));
-    }
-
-    // Set the cache type.
-    if (cacheType.equalsIgnoreCase("LRU")) {
-      accessOrder = true;
-    } else {
-      // Admin framework should only allow for either FIFO or LRU but
-      // we set the type to default here explicitly if it is not LRU.
-      cacheType = DEFAULT_FSCACHE_TYPE;
-      accessOrder = false;
-    }
-
-    // Initialize the index.
-    entryCacheIndex = new FileSystemEntryCacheIndex(this, accessOrder);
-
-    // Initialize locks.
-    cacheLock = new ReentrantReadWriteLock(true);
-    if (accessOrder) {
-      // In access-ordered linked hash maps, merely querying the map
-      // with get() is a structural modification.
-      cacheReadLock = cacheLock.writeLock();
-    } else {
-      cacheReadLock = cacheLock.readLock();
-    }
-    cacheWriteLock = cacheLock.writeLock();
-
-    // Setup the cache home.
-    try {
-      checkAndSetupCacheHome(cacheHome);
-    } catch (Exception e) {
-      logger.traceException(e);
-
-      // Not having any home directory for the cache db environment is a
-      // fatal error as we are unable to continue any further without it.
-      LocalizableMessage message =
-          ERR_FSCACHE_HOMELESS.get();
-      throw new InitializationException(message, e);
-    }
-
-    // Configure and open JE environment and cache database.
-    try {
-      entryCacheEnvConfig.setAllowCreate(true);
-      entryCacheEnv = new Environment(new File(cacheHome), entryCacheEnvConfig);
-      entryCacheEnv.setMutableConfig(entryCacheEnvMutableConfig);
-      entryCacheDBConfig = new DatabaseConfig();
-      entryCacheDBConfig.setAllowCreate(true);
-
-      // Configure the JE environment statistics to return only
-      // the values which do not incur some performance penalty.
-      entryCacheEnvStatsConfig.setFast(true);
-
-      // Remove old cache databases if this cache is not persistent.
-      if ( !persistentCache ) {
-        try {
-          entryCacheEnv.removeDatabase(null, INDEXCLASSDBNAME);
-        } catch (DatabaseNotFoundException e) {}
-        try {
-          entryCacheEnv.removeDatabase(null, ENTRYCACHEDBNAME);
-        } catch (DatabaseNotFoundException e) {}
-      }
-
-      entryCacheDB = entryCacheEnv.openDatabase(null,
-              ENTRYCACHEDBNAME, entryCacheDBConfig);
-      entryCacheClassDB =
-        entryCacheEnv.openDatabase(null, INDEXCLASSDBNAME, entryCacheDBConfig);
-      // Instantiate the class catalog
-      classCatalog = new StoredClassCatalog(entryCacheClassDB);
-      //This line causes an unchecked call error if the SuppressWarnings
-      //annotation is removed at the beginning of this method.
-      entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>(
-          classCatalog, FileSystemEntryCacheIndex.class);
-
-      // Get the root configuration object.
-      ServerManagementContext managementContext =
-        ServerManagementContext.getInstance();
-      RootCfg rootConfiguration =
-        managementContext.getRootConfiguration();
-
-      // Restoration is static and not subject to the current configuration
-      // constraints so that the persistent state is truly preserved and
-      // restored to the exact same state where we left off when the cache
-      // has been made persistent. The only exception to this is the backend
-      // offline state matching where entries that belong to backend which
-      // we cannot match offline state for are discarded from the cache.
-      if ( persistentCache &&
-          // If preload is requested there is no point restoring the cache.
-          !rootConfiguration.getGlobalConfiguration(
-          ).isEntryCachePreload()) {
-        // Retrieve cache index.
-        try {
-          DatabaseEntry indexData = new DatabaseEntry();
-          DatabaseEntry indexKey = new DatabaseEntry(
-              INDEXKEY.getBytes("UTF-8"));
-
-          // Persistent state report.
-          logger.info(NOTE_FSCACHE_RESTORE);
-
-          if (OperationStatus.SUCCESS ==
-              entryCacheDB.get(null, indexKey, indexData, LockMode.DEFAULT)) {
-            entryCacheIndex = entryCacheDataBinding.entryToObject(indexData);
-          } else {
-            throw new CacheIndexNotFoundException();
-          }
-          // Check cache index state.
-          if ((entryCacheIndex.dnMap.isEmpty()) ||
-              (entryCacheIndex.backendMap.isEmpty()) ||
-              (entryCacheIndex.offlineState.isEmpty())) {
-            throw new CacheIndexImpairedException();
-          } else {
-            // Restore entry cache maps from this index.
-
-            // Push maxEntries and make it unlimited til restoration complete.
-            AtomicLong currentMaxEntries = maxEntries;
-            maxEntries.set(DEFAULT_FSCACHE_MAX_ENTRIES);
-
-            // Compare last known offline states to offline states on startup.
-            Map<String,Long> currentBackendsState =
-                DirectoryServer.getOfflineBackendsStateIDs();
-            Set<String> offlineBackendSet =
-                entryCacheIndex.offlineState.keySet();
-            Iterator<String> offlineBackendIterator =
-                offlineBackendSet.iterator();
-            while (offlineBackendIterator.hasNext()) {
-              String backend = offlineBackendIterator.next();
-              Long offlineId = entryCacheIndex.offlineState.get(backend);
-              Long currentId = currentBackendsState.get(backend);
-              if ( !(offlineId.equals(currentId)) ) {
-                // Remove cache entries specific to this backend.
-                clearBackend(DirectoryServer.getBackend(backend));
-                logger.warn(WARN_FSCACHE_OFFLINE_STATE_FAIL, backend);
-              }
-            }
-            // Pop max entries limit.
-            maxEntries = currentMaxEntries;
-          }
-
-          // Persistent state report.
-          logger.info(NOTE_FSCACHE_RESTORE_REPORT, entryCacheIndex.dnMap.size());
-
-        } catch (CacheIndexNotFoundException e) {
-          logger.traceException(e);
-          logger.info(NOTE_FSCACHE_INDEX_NOT_FOUND);
-          clear();
-        } catch (CacheIndexImpairedException e) {
-          logger.traceException(e);
-          logger.error(ERR_FSCACHE_INDEX_IMPAIRED);
-          clear();
-        } catch (Exception e) {
-          logger.traceException(e);
-          logger.error(ERR_FSCACHE_CANNOT_LOAD_PERSISTENT_DATA);
-          clear();
-        }
-      }
-    } catch (Exception e) {
-      // If we got here it means we have failed to have a proper backend
-      // for this entry cache and there is absolutely no point going any
-      // farther from here.
-      logger.traceException(e);
-
-      LocalizableMessage message =
-          ERR_FSCACHE_CANNOT_INITIALIZE.get(
-          (e.getCause() != null ? e.getCause().getMessage() :
-            stackTraceToSingleLineString(e)));
-      throw new InitializationException(message, e);
-    }
-
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void finalizeEntryCache() {
-
-    cacheWriteLock.lock();
-
-    try {
-      registeredConfiguration.removeFileSystemChangeListener(this);
-
-      // Store index/maps in case of persistent cache. Since the cache database
-      // already exist at this point all we have to do is to serialize cache
-      // index maps @see FileSystemEntryCacheIndex and put them under indexkey
-      // allowing for the index to be restored and cache contents reused upon
-      // the next initialization. If this cache is empty skip persisting phase.
-      if (persistentCache && !entryCacheIndex.dnMap.isEmpty()) {
-        // There must be at least one backend at this stage.
-        entryCacheIndex.offlineState =
-          DirectoryServer.getOfflineBackendsStateIDs();
-
-        // Store the index.
-        try {
-          DatabaseEntry indexData = new DatabaseEntry();
-
-          // Persistent state save report.
-          logger.info(NOTE_FSCACHE_SAVE);
-          //This line causes an unchecked call error if the SuppressWarnings
-          //annotation is removed at the beginning of this method.
-          entryCacheDataBinding.objectToEntry(entryCacheIndex, indexData);
-          DatabaseEntry indexKey =
-            new DatabaseEntry(INDEXKEY.getBytes("UTF-8"));
-          if (OperationStatus.SUCCESS != entryCacheDB.put(null, indexKey,
-              indexData)) {
-            throw new Exception();
-          }
-        } catch (Exception e) {
-          logger.traceException(e);
-          logger.error(ERR_FSCACHE_CANNOT_STORE_PERSISTENT_DATA);
-        }
-
-        // Persistent state save report.
-        logger.info(NOTE_FSCACHE_SAVE_REPORT, entryCacheIndex.dnMap.size());
-      }
-
-      // Close JE databases and environment and clear all the maps.
-      try {
-        entryCacheIndex.backendMap.clear();
-        entryCacheIndex.dnMap.clear();
-        if (entryCacheDB != null) {
-          entryCacheDB.close();
-        }
-        if (entryCacheClassDB != null) {
-          entryCacheClassDB.close();
-        }
-        if (entryCacheEnv != null) {
-          // Remove cache and index dbs if this cache is not persistent.
-          if (!persistentCache) {
-            try {
-              entryCacheEnv.removeDatabase(null, INDEXCLASSDBNAME);
-            } catch (DatabaseNotFoundException e) {}
-            try {
-              entryCacheEnv.removeDatabase(null, ENTRYCACHEDBNAME);
-            } catch (DatabaseNotFoundException e) {}
-          }
-          entryCacheEnv.cleanLog();
-          entryCacheEnv.close();
-        }
-      } catch (Exception e) {
-        logger.traceException(e);
-
-        // That is ok, JE verification and repair on startup should take care of
-        // this so if there are any unrecoverable errors during next startup
-        // and we are unable to handle and cleanup them we will log errors then.
-      }
-    } finally {
-      cacheWriteLock.unlock();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean containsEntry(DN entryDN)
-  {
-    if (entryDN == null) {
-      return false;
-    }
-
-    // Indicate whether the DN map contains the specified DN.
-    boolean containsEntry = false;
-    cacheReadLock.lock();
-    try {
-      containsEntry = entryCacheIndex.dnMap.containsKey(
-        entryDN.toNormalizedString());
-    } finally {
-      cacheReadLock.unlock();
-    }
-    return containsEntry;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Entry getEntry(DN entryDN) {
-    // Get the entry from the DN map if it is present.  If not, then return
-    // null.
-    Entry entry = null;
-    cacheReadLock.lock();
-    try {
-      // Use get to generate entry access.
-      if (entryCacheIndex.dnMap.get(entryDN.toNormalizedString()) != null) {
-        entry = getEntryFromDB(entryDN);
-        // Indicate cache hit.
-        cacheHits.getAndIncrement();
-      } else {
-        // Indicate cache miss.
-        cacheMisses.getAndIncrement();
-      }
-    } finally {
-      cacheReadLock.unlock();
-    }
-    return entry;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public long getEntryID(DN entryDN) {
-    long entryID = -1;
-    cacheReadLock.lock();
-    try {
-      Long eid = entryCacheIndex.dnMap.get(entryDN.toNormalizedString());
-      if (eid != null) {
-        entryID = eid.longValue();
-      }
-    } finally {
-      cacheReadLock.unlock();
-    }
-    return entryID;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public DN getEntryDN(Backend backend, long entryID) {
-    DN entryDN = null;
-    cacheReadLock.lock();
-    try {
-      // Get the map for the provided backend.  If it isn't present, then
-      // return null.
-      Map<Long, String> map = entryCacheIndex.backendMap.get(backend
-          .getBackendID());
-      if (map != null)
-      {
-        // Get the entry DN from the map by its ID.  If it isn't present,
-        // then return null.
-        entryDN = DN.valueOf(map.get(entryID));
-      }
-    } catch (Exception e) {
-      // Ignore.
-    } finally {
-      cacheReadLock.unlock();
-    }
-    return entryDN;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void putEntry(Entry entry, Backend backend, long entryID)
-  {
-    try {
-      // TODO: Cache the buffer?
-      ByteStringBuilder buffer = new ByteStringBuilder();
-      entry.encode(buffer, encodeConfig);
-      putEntryToDB(entry.getName().toNormalizedString(),
-        backend, entryID, buffer);
-    } catch (Exception e) {
-      logger.traceException(e);
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean putEntryIfAbsent(Entry entry, Backend backend, long entryID)
-  {
-    cacheReadLock.lock();
-    try {
-      // See if the entry already exists in the cache. If it does, then we
-      // will fail and not actually store the entry.
-      if (entryCacheIndex.dnMap.containsKey(
-        entry.getName().toNormalizedString())) {
-        return false;
-      }
-    } finally {
-      cacheReadLock.unlock();
-    }
-    try {
-      // TODO: Cache the buffer?
-      ByteStringBuilder buffer = new ByteStringBuilder();
-      entry.encode(buffer, encodeConfig);
-      return putEntryToDB(entry.getName().toNormalizedString(),
-        backend, entryID, buffer);
-    } catch (Exception e) {
-      logger.traceException(e);
-      // We can't rule out the possibility of a conflict, so return false.
-      return false;
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void removeEntry(DN entryDN) {
-
-    cacheWriteLock.lock();
-
-    try {
-      Long entryID = entryCacheIndex.dnMap.get(entryDN.toNormalizedString());
-      if (entryID == null) {
-        return;
-      }
-      Set<String> backendSet = entryCacheIndex.backendMap.keySet();
-      Iterator<String> backendIterator = backendSet.iterator();
-      while (backendIterator.hasNext()) {
-        Map<Long,String> map = entryCacheIndex.backendMap.get(
-          backendIterator.next());
-        if ((map.get(entryID) != null) &&
-            (map.get(entryID).equals(entryDN.toNormalizedString()))) {
-          map.remove(entryID);
-          // If this backend becomes empty now
-          // remove it from the backend map.
-          if (map.isEmpty()) {
-            backendIterator.remove();
-          }
-          break;
-        }
-      }
-      entryCacheIndex.dnMap.remove(entryDN.toNormalizedString());
-      entryCacheDB.delete(null,
-        new DatabaseEntry(entryDN.toNormalizedString().getBytes("UTF-8")));
-    } catch (Exception e) {
-      logger.traceException(e);
-    } finally {
-      cacheWriteLock.unlock();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void clear() {
-
-    cacheWriteLock.lock();
-
-    try {
-      entryCacheIndex.dnMap.clear();
-      entryCacheIndex.backendMap.clear();
-
-      try {
-        if ((entryCacheDB != null) && (entryCacheEnv != null) &&
-            (entryCacheClassDB != null) && (entryCacheDBConfig != null)) {
-          entryCacheDBConfig = entryCacheDB.getConfig();
-          entryCacheDB.close();
-          entryCacheClassDB.close();
-          entryCacheEnv.truncateDatabase(null, ENTRYCACHEDBNAME, false);
-          entryCacheEnv.truncateDatabase(null, INDEXCLASSDBNAME, false);
-          entryCacheEnv.cleanLog();
-          entryCacheDB = entryCacheEnv.openDatabase(null, ENTRYCACHEDBNAME,
-            entryCacheDBConfig);
-          entryCacheClassDB = entryCacheEnv.openDatabase(null,
-            INDEXCLASSDBNAME, entryCacheDBConfig);
-          // Instantiate the class catalog
-          classCatalog = new StoredClassCatalog(entryCacheClassDB);
-          //This line causes an unchecked call error if the SuppressWarnings
-          //annotation is removed at the beginning of this method.
-          entryCacheDataBinding = new SerialBinding<FileSystemEntryCacheIndex>(
-              classCatalog, FileSystemEntryCacheIndex.class);
-        }
-      } catch (Exception e) {
-        logger.traceException(e);
-      }
-    } finally {
-      cacheWriteLock.unlock();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void clearBackend(Backend backend) {
-
-    cacheWriteLock.lock();
-
-    try {
-      Map<Long, String> backendEntriesMap =
-        entryCacheIndex.backendMap.get(backend.getBackendID());
-
-      try {
-        if (backendEntriesMap == null) {
-          // No entries were in the cache for this backend,
-          // so we can return without doing anything.
-          return;
-        }
-        int entriesExamined = 0;
-        Iterator<Long> backendEntriesIterator =
-          backendEntriesMap.keySet().iterator();
-        while (backendEntriesIterator.hasNext()) {
-          Long entryID = backendEntriesIterator.next();
-          DN entryDN = DN.valueOf(backendEntriesMap.get(entryID));
-          entryCacheDB.delete(null, new DatabaseEntry(
-            entryDN.toNormalizedString().getBytes("UTF-8")));
-          backendEntriesIterator.remove();
-          entryCacheIndex.dnMap.remove(entryDN.toNormalizedString());
-
-          // This can take a while, so we'll periodically release and
-          // re-acquire the lock in case anyone else is waiting on it
-          // so this doesn't become a stop-the-world event as far as
-          // the cache is concerned.
-          entriesExamined++;
-          if ((entriesExamined % 1000) == 0) {
-            cacheWriteLock.unlock();
-            Thread.yield();
-            cacheWriteLock.lock();
-          }
-        }
-
-        // This backend is empty now, remove it from the backend map.
-        entryCacheIndex.backendMap.remove(backend.getBackendID());
-      } catch (Exception e) {
-        logger.traceException(e);
-      }
-    } finally {
-      cacheWriteLock.unlock();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void clearSubtree(DN baseDN) {
-    // Determine which backend should be used for the provided base DN.  If
-    // there is none, then we don't need to do anything.
-    Backend backend = DirectoryServer.getBackend(baseDN);
-    if (backend == null)
-    {
-      return;
-    }
-
-    // Acquire a lock on the cache.  We should not return until the cache has
-    // been cleared, so we will block until we can obtain the lock.
-    cacheWriteLock.lock();
-
-    // At this point, it is absolutely critical that we always release the lock
-    // before leaving this method, so do so in a finally block.
-    try
-    {
-      clearSubtree(baseDN, backend);
-    }
-    catch (Exception e)
-    {
-      logger.traceException(e);
-      // This shouldn't happen, but there's not much that we can do if it does.
-    }
-    finally
-    {
-      cacheWriteLock.unlock();
-    }
-  }
-
-  /**
-   * Clears all entries at or below the specified base DN that are associated
-   * with the given backend.  The caller must already hold the cache lock.
-   *
-   * @param  baseDN   The base DN below which all entries should be flushed.
-   * @param  backend  The backend for which to remove the appropriate entries.
-   */
-  private void clearSubtree(DN baseDN, Backend backend) {
-    // See if there are any entries for the provided backend in the cache.  If
-    // not, then return.
-    Map<Long,String> map =
-      entryCacheIndex.backendMap.get(backend.getBackendID());
-    if (map == null)
-    {
-      // No entries were in the cache for this backend, so we can return without
-      // doing anything.
-      return;
-    }
-
-    // Since the provided base DN could hold a subset of the information in the
-    // specified backend, we will have to do this by iterating through all the
-    // entries for that backend.  Since this could take a while, we'll
-    // periodically release and re-acquire the lock in case anyone else is
-    // waiting on it so this doesn't become a stop-the-world event as far as the
-    // cache is concerned.
-    int entriesExamined = 0;
-    Iterator<String> iterator = map.values().iterator();
-    while (iterator.hasNext())
-    {
-      try {
-        DN entryDN = DN.valueOf(iterator.next());
-        if (entryDN.isDescendantOf(baseDN)) {
-          iterator.remove();
-          entryCacheIndex.dnMap.remove(entryDN.toNormalizedString());
-          try {
-            entryCacheDB.delete(null,
-              new DatabaseEntry(
-              entryDN.toNormalizedString().getBytes("UTF-8")));
-          } catch (Exception e) {
-            logger.traceException(e);
-          }
-        }
-
-        entriesExamined++;
-        if ((entriesExamined % 1000) == 0) {
-          cacheWriteLock.unlock();
-          Thread.yield();
-          cacheWriteLock.lock();
-        }
-      } catch (Exception e) {
-        // Ignore.
-      }
-    }
-
-    // If this backend becomes empty now
-    // remove it from the backend map.
-    if (map.isEmpty()) {
-      entryCacheIndex.backendMap.remove(backend.getBackendID());
-    }
-
-    // See if the backend has any subordinate backends.  If so, then process
-    // them recursively.
-    for (Backend subBackend : backend.getSubordinateBackends())
-    {
-      boolean isAppropriate = false;
-      for (DN subBase : subBackend.getBaseDNs())
-      {
-        if (subBase.isDescendantOf(baseDN))
-        {
-          isAppropriate = true;
-          break;
-        }
-      }
-
-      if (isAppropriate)
-      {
-        clearSubtree(baseDN, subBackend);
-      }
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void handleLowMemory() {
-    // This is about all we can do.
-    if (entryCacheEnv != null) {
-      try {
-        // Free some JVM memory.
-        entryCacheEnv.evictMemory();
-        // Free some main memory/space.
-        entryCacheEnv.cleanLog();
-      } catch (Exception e) {
-        logger.traceException(e);
-      }
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean isConfigurationAcceptable(EntryCacheCfg configuration,
-                                           List<LocalizableMessage> unacceptableReasons)
-  {
-    FileSystemEntryCacheCfg config = (FileSystemEntryCacheCfg) configuration;
-    return isConfigurationChangeAcceptable(config, unacceptableReasons);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean isConfigurationChangeAcceptable(
-      FileSystemEntryCacheCfg configuration,
-      List<LocalizableMessage> unacceptableReasons
-      )
-  {
-    boolean applyChanges = false;
-    EntryCacheCommon.ConfigErrorHandler errorHandler =
-      EntryCacheCommon.getConfigErrorHandler (
-          EntryCacheCommon.ConfigPhase.PHASE_ACCEPTABLE,
-          unacceptableReasons,
-          null
-        );
-    processEntryCacheConfig (configuration, applyChanges, errorHandler);
-
-    return errorHandler.getIsAcceptable();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ConfigChangeResult applyConfigurationChange(
-      FileSystemEntryCacheCfg configuration
-      )
-  {
-    boolean applyChanges = true;
-    ArrayList<LocalizableMessage> errorMessages = new ArrayList<LocalizableMessage>();
-    EntryCacheCommon.ConfigErrorHandler errorHandler =
-      EntryCacheCommon.getConfigErrorHandler (
-          EntryCacheCommon.ConfigPhase.PHASE_APPLY, null, errorMessages
-          );
-
-    // Do not apply changes unless this cache is enabled.
-    if (configuration.isEnabled()) {
-      processEntryCacheConfig (configuration, applyChanges, errorHandler);
-    }
-
-    boolean adminActionRequired = errorHandler.getIsAdminActionRequired();
-    ConfigChangeResult changeResult = new ConfigChangeResult(
-        errorHandler.getResultCode(),
-        adminActionRequired,
-        errorHandler.getErrorMessages()
-        );
-
-    return changeResult;
-  }
-
-  /**
-   * Parses the provided configuration and configure the entry cache.
-   *
-   * @param configuration  The new configuration containing the changes.
-   * @param applyChanges   If true then take into account the new configuration.
-   * @param errorHandler   An handler used to report errors.
-   *
-   * @return  <CODE>true</CODE> if configuration is acceptable,
-   *          or <CODE>false</CODE> otherwise.
-   */
-  public boolean processEntryCacheConfig(
-      FileSystemEntryCacheCfg             configuration,
-      boolean                             applyChanges,
-      EntryCacheCommon.ConfigErrorHandler errorHandler
-      )
-  {
-    // Local variables to read configuration.
-    DN                       newConfigEntryDN;
-    long                     newLockTimeout;
-    long                     newMaxEntries;
-    long                     newMaxAllowedMemory;
-    HashSet<SearchFilter>    newIncludeFilters = null;
-    HashSet<SearchFilter>    newExcludeFilters = null;
-    int                      newJECachePercent;
-    long                     newJECacheSize;
-    boolean                  newPersistentCache;
-    boolean                  newCompactEncoding;
-    String                   newCacheType = DEFAULT_FSCACHE_TYPE;
-    String                   newCacheHome = DEFAULT_FSCACHE_HOME;
-    SortedSet<String>        newJEProperties;
-
-    EnvironmentMutableConfig newMutableEnvConfig =
-      new EnvironmentMutableConfig();
-    EnvironmentConfig        newEnvConfig =
-      new EnvironmentConfig();
-
-    // Read configuration.
-    newConfigEntryDN = configuration.dn();
-    newLockTimeout   = configuration.getLockTimeout();
-
-    // If the value of zero arrives make sure it is traslated
-    // to the maximum possible value we can cap maxEntries to.
-    newMaxEntries = configuration.getMaxEntries();
-    if (newMaxEntries <= 0) {
-      newMaxEntries = DEFAULT_FSCACHE_MAX_ENTRIES;
-    }
-
-    // Maximum memory/space this cache can utilize.
-    newMaxAllowedMemory = configuration.getMaxMemorySize();
-
-    // Determine JE cache percent.
-    newJECachePercent = configuration.getDBCachePercent();
-
-    // Determine JE cache size.
-    newJECacheSize = configuration.getDBCacheSize();
-
-    // Check if this cache is persistent.
-    newPersistentCache = configuration.isPersistentCache();
-
-    // Check if this cache should use compact encoding.
-    newCompactEncoding = configuration.isCompactEncoding();
-
-    // Get native JE properties.
-    newJEProperties = configuration.getJEProperty();
-
-    switch (errorHandler.getConfigPhase())
-    {
-    case PHASE_INIT:
-      // Determine the cache type.
-      newCacheType = configuration.getCacheType().toString();
-
-      // Determine the cache home.
-      newCacheHome = configuration.getCacheDirectory();
-
-      newIncludeFilters = EntryCacheCommon.getFilters(
-          configuration.getIncludeFilter(),
-          ERR_CACHE_INVALID_INCLUDE_FILTER,
-          errorHandler,
-          newConfigEntryDN
-          );
-      newExcludeFilters = EntryCacheCommon.getFilters (
-          configuration.getExcludeFilter(),
-          ERR_CACHE_INVALID_EXCLUDE_FILTER,
-          errorHandler,
-          newConfigEntryDN
-          );
-      // JE configuration properties.
-      try {
-        newMutableEnvConfig.setCachePercent((newJECachePercent != 0 ?
-          newJECachePercent :
-          EnvironmentConfig.DEFAULT.getCachePercent()));
-      } catch (Exception e) {
-        logger.traceException(e);
-        errorHandler.reportError(
-          ERR_FSCACHE_CANNOT_SET_JE_MEMORY_PCT.get(),
-          false,
-          DirectoryServer.getServerErrorResultCode()
-          );
-      }
-      try {
-        newMutableEnvConfig.setCacheSize(newJECacheSize);
-      } catch (Exception e) {
-        logger.traceException(e);
-        errorHandler.reportError(
-          ERR_FSCACHE_CANNOT_SET_JE_MEMORY_SIZE.get(),
-          false,
-          DirectoryServer.getServerErrorResultCode()
-          );
-      }
-      // JE native properties.
-      try {
-        newEnvConfig = ConfigurableEnvironment.setJEProperties(
-          newEnvConfig, newJEProperties, configAttrMap);
-      } catch (Exception e) {
-        logger.traceException(e);
-        errorHandler.reportError(
-          ERR_FSCACHE_CANNOT_SET_JE_PROPERTIES.get(e.getMessage()),
-          false, DirectoryServer.getServerErrorResultCode());
-      }
-      break;
-    case PHASE_ACCEPTABLE:  // acceptable and apply are using the same
-    case PHASE_APPLY:       // error ID codes
-      newIncludeFilters = EntryCacheCommon.getFilters (
-          configuration.getIncludeFilter(),
-          ERR_CACHE_INVALID_INCLUDE_FILTER,
-          errorHandler,
-          newConfigEntryDN
-          );
-      newExcludeFilters = EntryCacheCommon.getFilters (
-          configuration.getExcludeFilter(),
-          ERR_CACHE_INVALID_EXCLUDE_FILTER,
-          errorHandler,
-          newConfigEntryDN
-          );
-      // Iterate through native JE properties.
-      try {
-        Map<String, ConfigParam> paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
-        // If this entry cache is disabled then there is no open JE
-        // environment to check against, skip mutable check if so.
-        if (configuration.isEnabled()) {
-          newMutableEnvConfig =
-            ConfigurableEnvironment.setJEProperties(
-            entryCacheEnv.getConfig(), newJEProperties, configAttrMap);
-          EnvironmentConfig oldEnvConfig = entryCacheEnv.getConfig();
-          for (String jeEntry : newJEProperties) {
-            // There is no need to validate properties yet again.
-            StringTokenizer st = new StringTokenizer(jeEntry, "=");
-            if (st.countTokens() == 2) {
-              String jePropertyName = st.nextToken();
-              String jePropertyValue = st.nextToken();
-              ConfigParam param = paramsMap.get(jePropertyName);
-              if (!param.isMutable()) {
-                String oldValue = oldEnvConfig.getConfigParam(param.getName());
-                String newValue = jePropertyValue;
-                if (!oldValue.equalsIgnoreCase(newValue)) {
-                  LocalizableMessage message =
-                    INFO_CONFIG_JE_PROPERTY_REQUIRES_RESTART.get(
-                    jePropertyName);
-                  errorHandler.reportError(message, true, ResultCode.SUCCESS,
-                    true);
-                  if (logger.isTraceEnabled()) {
-                    logger.trace("The change to the following property " +
-                      "will take effect when the component is restarted: " +
-                      jePropertyName);
-                  }
-                }
-              }
-            }
-          }
-        } else {
-          newMutableEnvConfig =
-            ConfigurableEnvironment.setJEProperties(
-            new EnvironmentConfig(), newJEProperties, configAttrMap);
-        }
-      } catch (ConfigException ce) {
-        errorHandler.reportError(ce.getMessageObject(),
-          false, DirectoryServer.getServerErrorResultCode());
-      } catch (Exception e) {
-        errorHandler.reportError(
-          LocalizableMessage.raw(stackTraceToSingleLineString(e)),
-          false, DirectoryServer.getServerErrorResultCode());
-      }
-      break;
-    }
-
-    if (applyChanges && errorHandler.getIsAcceptable())
-    {
-      switch (errorHandler.getConfigPhase()) {
-      case PHASE_INIT:
-        cacheType = newCacheType;
-        cacheHome = newCacheHome;
-        entryCacheEnvConfig = newEnvConfig;
-        entryCacheEnvMutableConfig = newMutableEnvConfig;
-        break;
-      case PHASE_APPLY:
-        try {
-            newMutableEnvConfig =
-              entryCacheEnv.getMutableConfig();
-            newMutableEnvConfig.setCachePercent((newJECachePercent != 0 ?
-              newJECachePercent :
-              EnvironmentConfig.DEFAULT.getCachePercent()));
-            entryCacheEnv.setMutableConfig(newMutableEnvConfig);
-            entryCacheEnv.evictMemory();
-        } catch (Exception e) {
-            logger.traceException(e);
-            errorHandler.reportError(
-              ERR_FSCACHE_CANNOT_SET_JE_MEMORY_PCT.get(),
-              false,
-              DirectoryServer.getServerErrorResultCode()
-              );
-        }
-        try {
-            newMutableEnvConfig =
-              entryCacheEnv.getMutableConfig();
-            newMutableEnvConfig.setCacheSize(newJECacheSize);
-            entryCacheEnv.setMutableConfig(newMutableEnvConfig);
-            entryCacheEnv.evictMemory();
-        } catch (Exception e) {
-            logger.traceException(e);
-            errorHandler.reportError(
-              ERR_FSCACHE_CANNOT_SET_JE_MEMORY_SIZE.get(),
-              false,
-              DirectoryServer.getServerErrorResultCode()
-              );
-        }
-        try {
-          EnvironmentConfig oldEnvConfig = entryCacheEnv.getConfig();
-          newEnvConfig = ConfigurableEnvironment.setJEProperties(
-            oldEnvConfig, newJEProperties, configAttrMap);
-          // This takes care of changes to the JE environment for those
-          // properties that are mutable at runtime.
-          entryCacheEnv.setMutableConfig(newEnvConfig);
-        } catch (Exception e) {
-          logger.traceException(e);
-            errorHandler.reportError(
-              ERR_FSCACHE_CANNOT_SET_JE_PROPERTIES.get(e.getMessage()),
-              false,
-              DirectoryServer.getServerErrorResultCode()
-              );
-        }
-        break;
-      }
-
-      maxEntries       = new AtomicLong(newMaxEntries);
-      maxAllowedMemory = newMaxAllowedMemory;
-      persistentCache  = newPersistentCache;
-
-      encodeConfig     = new EntryEncodeConfig(true,
-        newCompactEncoding, newCompactEncoding);
-
-      lockTimeout = newLockTimeout;
-      setIncludeFilters(newIncludeFilters);
-      setExcludeFilters(newExcludeFilters);
-
-      registeredConfiguration = configuration;
-    }
-
-    return errorHandler.getIsAcceptable();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ArrayList<Attribute> getMonitorData()
-  {
-    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
-
-    try {
-      attrs = EntryCacheCommon.getGenericMonitorData(
-        new Long(cacheHits.longValue()),
-        // If cache misses is maintained by default cache
-        // get it from there and if not point to itself.
-        DirectoryServer.getEntryCache().getCacheMisses(),
-        new Long(entryCacheEnv.getStats(
-          entryCacheEnvStatsConfig).getTotalLogSize()),
-        new Long(maxAllowedMemory),
-        new Long(entryCacheIndex.dnMap.size()),
-        (((maxEntries.longValue() != Integer.MAX_VALUE) &&
-          (maxEntries.longValue() != Long.MAX_VALUE)) ?
-           new Long(maxEntries.longValue()) : new Long(0))
-        );
-    } catch (Exception e) {
-      logger.traceException(e);
-    }
-
-    return attrs;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Long getCacheCount()
-  {
-    return new Long(entryCacheIndex.dnMap.size());
-  }
-
-  /**
-   * Retrieves and decodes the entry with the specified DN from JE backend db.
-   *
-   * @param  entryDN   The DN of the entry to retrieve.
-   *
-   * @return  The requested entry if it is present in the cache, or
-   *          <CODE>null</CODE> if it is not present.
-   */
-  private Entry getEntryFromDB(DN entryDN)
-  {
-    DatabaseEntry cacheEntryKey = new DatabaseEntry();
-    DatabaseEntry primaryData = new DatabaseEntry();
-
-    try {
-      // Get the primary key and data.
-      cacheEntryKey.setData(entryDN.toNormalizedString().getBytes("UTF-8"));
-      if (entryCacheDB.get(null, cacheEntryKey,
-              primaryData,
-              LockMode.DEFAULT) == OperationStatus.SUCCESS) {
-
-        Entry entry = Entry.decode(
-            ByteString.wrap(primaryData.getData()).asReader());
-        entry.setDN(entryDN);
-        return entry;
-      } else {
-        throw new Exception();
-      }
-    } catch (Exception e) {
-      logger.traceException(e);
-      logger.error(ERR_FSCACHE_CANNOT_RETRIEVE_ENTRY);
-    }
-    return null;
-  }
-
-  /**
-   * Encodes and stores the entry in the JE backend db.
-   *
-   * @param  backend  The backend with which the entry is associated.
-   * @param  entryID  The entry ID within the provided backend that uniquely
-   *                  identifies the specified entry.
-   *
-   * @return  <CODE>false</CODE> if some problem prevented the method from
-   *          completing successfully, or <CODE>true</CODE> if the entry
-   *          was either stored or the cache determined that this entry
-   *          should never be cached for some reason.
-   */
-  private boolean putEntryToDB(String dnString,
-                               Backend backend,
-                               long entryID,
-                               ByteStringBuilder entryBytes) {
-    try {
-      // Obtain a lock on the cache.  If this fails, then don't do anything.
-      if (!cacheWriteLock.tryLock(lockTimeout, TimeUnit.MILLISECONDS)) {
-        return false;
-      }
-      // See if the current fs space usage is within acceptable constraints. If
-      // so, then add the entry to the cache (or replace it if it is already
-      // present).  If not, then remove an existing entry and don't add the new
-      // entry.
-      // Zero means unlimited here.
-      if (maxAllowedMemory != 0) {
-        // Get approximate current total log size of JE environment in bytes.
-        long usedMemory =
-            entryCacheEnv.getStats(entryCacheEnvStatsConfig).getTotalLogSize();
-
-        // TODO: Check and log a warning if usedMemory hits default or
-        // configurable watermark, see Issue 1735.
-
-        if (usedMemory > maxAllowedMemory) {
-          long savedMaxEntries = maxEntries.longValue();
-          // Cap maxEntries artificially but dont let it go negative under
-          // any circumstances.
-          maxEntries.set((entryCacheIndex.dnMap.isEmpty() ? 0 :
-            entryCacheIndex.dnMap.size() - 1));
-          // Add the entry to the map to trigger remove of the eldest entry.
-          // @see LinkedHashMapRotator.removeEldestEntry() for more details.
-          entryCacheIndex.dnMap.put(dnString, entryID);
-          // Restore the map and maxEntries.
-          entryCacheIndex.dnMap.remove(dnString);
-          maxEntries.set(savedMaxEntries);
-          // We'll always return true in this case, even tho we didn't actually
-          // add the entry due to memory constraints.
-          return true;
-        }
-      }
-
-      // Create key.
-      DatabaseEntry cacheEntryKey = new DatabaseEntry();
-      cacheEntryKey.setData(dnString.getBytes("UTF-8"));
-
-      // Create data and put this cache entry into the database.
-      if (entryCacheDB.put(null, cacheEntryKey,
-          new DatabaseEntry(entryBytes.getBackingArray(), 0,
-              entryBytes.length())) == OperationStatus.SUCCESS) {
-        // Add the entry to the cache index maps.
-        Map<Long,String> map =
-          entryCacheIndex.backendMap.get(backend.getBackendID());
-        if (map == null) {
-          map = new HashMap<Long,String>();
-          map.put(entryID, dnString);
-          entryCacheIndex.backendMap.put(backend.getBackendID(), map);
-        } else {
-          map.put(entryID, dnString);
-        }
-        entryCacheIndex.dnMap.put(dnString, entryID);
-      }
-
-      // We'll always return true in this case, even if we didn't actually add
-      // the entry due to memory constraints.
-      return true;
-    } catch (Exception e) {
-      logger.traceException(e);
-      logger.error(ERR_FSCACHE_CANNOT_STORE_ENTRY);
-      return false;
-    } finally {
-      if (cacheLock.isWriteLockedByCurrentThread()) {
-        cacheWriteLock.unlock();
-      }
-    }
-  }
-
-  /**
-   * 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;
-    File cacheHomeDir = new File(cacheHome);
-    if (cacheHomeDir.exists() &&
-        cacheHomeDir.canRead() &&
-        cacheHomeDir.canWrite()) {
-      cacheHasHome = true;
-    } else {
-      try {
-        cacheHasHome = cacheHomeDir.mkdirs();
-      } catch (SecurityException e) {
-        cacheHasHome = false;
-      }
-    }
-    if ( cacheHasHome ) {
-      // TODO: Investigate if its feasible to employ SetFileAttributes()
-      // FILE_ATTRIBUTE_TEMPORARY attribute on Windows via native code.
-      if(FilePermission.canSetPermissions()) {
-        try {
-          if(!FilePermission.setPermissions(cacheHomeDir,
-              CACHE_HOME_PERMISSIONS)) {
-            throw new Exception();
-          }
-        } catch(Exception e) {
-          // Log a warning that the permissions were not set.
-          logger.warn(WARN_FSCACHE_SET_PERMISSIONS_FAILED, cacheHome);
-        }
-      }
-    } else {
-      throw new Exception();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public String toVerboseString()
-  {
-    StringBuilder sb = new StringBuilder();
-
-    Map<String,Long> dnMapCopy;
-    Map<String,Map<Long,String>> backendMapCopy;
-
-    // Grab write lock to prevent any modifications
-    // to the cache maps until a snapshot is taken.
-    cacheWriteLock.lock();
-    try {
-      // Examining the real maps will hold the lock
-      // and can cause map modifications in case of
-      // any access order maps, make copies instead.
-      dnMapCopy = new LinkedHashMap<String,Long>(entryCacheIndex.dnMap);
-      backendMapCopy =
-        new HashMap<String,Map<Long,String>>
-          (entryCacheIndex.backendMap);
-    } finally {
-      cacheWriteLock.unlock();
-    }
-
-    // Check dnMap first.
-    for (String dn : dnMapCopy.keySet()) {
-      sb.append(dn);
-      sb.append(":");
-      sb.append(dnMapCopy.get(dn) != null ? dnMapCopy.get(dn) : null);
-      sb.append(":");
-      String backendID = null;
-      Iterator<String> backendIterator = backendMapCopy.keySet().iterator();
-      while (backendIterator.hasNext()) {
-        backendID = backendIterator.next();
-        Map<Long, String> map = backendMapCopy.get(backendID);
-        if ((map != null) &&
-            (map.get(dnMapCopy.get(dn)) != null) &&
-            (map.get(dnMapCopy.get(dn)).equals(dn))) {
-          break;
-        }
-      }
-      sb.append(backendID);
-      sb.append(ServerConstants.EOL);
-    }
-
-    // See if there is anything on backendMap that isnt reflected on dnMap
-    // in case maps went out of sync.
-    Iterator<String> backendIterator = backendMapCopy.keySet().iterator();
-    while (backendIterator.hasNext()) {
-      String backendID = backendIterator.next();
-      Map<Long, String> map = backendMapCopy.get(backendID);
-      for (Long id : map.keySet()) {
-        if (!dnMapCopy.containsKey(map.get(id)) || map.get(id) == null) {
-          sb.append((map.get(id) != null ? map.get(id) : null));
-          sb.append(":");
-          sb.append(id.toString());
-          sb.append(":");
-          sb.append(backendID);
-          sb.append(ServerConstants.EOL);
-        }
-      }
-    }
-
-    String verboseString = sb.toString();
-
-    return (verboseString.length() > 0 ? verboseString : null);
-  }
-
-  /**
-   * This method is called each time we add a new key/value pair to the map.
-   * The eldest entry is selected by the LinkedHashMap implementation based
-   * on the access order configured.
-   *
-   * @param  eldest  The least recently inserted entry in the map, or if
-   *                 this is an access-ordered map, the least recently
-   *                 accessed entry. This is the entry that will be
-   *                 removed it this method returns true. If the map was
-   *                 empty prior to the put or putAll invocation resulting
-   *                 in this invocation, this will be the entry that was
-   *                 just inserted; in other words, if the map contains a
-   *                 single entry, the eldest entry is also the newest.
-   *
-   * @return boolean {@code true} if the eldest entry should be removed
-   *                 from the map; {@code false} if it should be retained.
-   */
-  protected boolean removeEldestEntry(Map.Entry<String, Long> eldest) {
-    // Check if we hit the limit on max entries and if so remove
-    // the eldest entry otherwise do nothing.
-    if (entryCacheIndex.dnMap.size() > maxEntries.longValue()) {
-      DatabaseEntry cacheEntryKey = new DatabaseEntry();
-      cacheWriteLock.lock();
-      try {
-        // Remove the the eldest entry from supporting maps.
-        String entryStringDN = eldest.getKey();
-        long entryID = eldest.getValue();
-        cacheEntryKey.setData(entryStringDN.getBytes("UTF-8"));
-        Set<String> backendSet = entryCacheIndex.backendMap.keySet();
-        Iterator<String> backendIterator = backendSet.iterator();
-        while (backendIterator.hasNext()) {
-          Map<Long, String> map = entryCacheIndex.backendMap.get(
-            backendIterator.next());
-          if ((map.get(entryID) != null) &&
-            (map.get(entryID).equals(entryStringDN))) {
-            map.remove(entryID);
-            // If this backend becomes empty now
-            // remove it from the backend map.
-            if (map.isEmpty()) {
-              backendIterator.remove();
-            }
-            break;
-          }
-        }
-        // Remove the the eldest entry from the database.
-        entryCacheDB.delete(null, cacheEntryKey);
-      } catch (Exception e) {
-        logger.traceException(e);
-      } finally {
-        cacheWriteLock.unlock();
-      }
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  /**
-   * This exception should be thrown if an error occurs while
-   * trying to locate and load persistent cache index from
-   * the existing entry cache database.
-   */
-  private class CacheIndexNotFoundException extends OpenDsException {
-    static final long serialVersionUID = 6444756053577853869L;
-    public CacheIndexNotFoundException() {}
-  }
-
-  /**
-   * This exception should be thrown if persistent cache index
-   * found in the existing entry cache database is determined
-   * to be empty, inconsistent or damaged.
-   */
-  private class CacheIndexImpairedException extends OpenDsException {
-    static final long serialVersionUID = -369455697709478407L;
-    public CacheIndexImpairedException() {}
-  }
-
-}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCacheIndex.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCacheIndex.java
deleted file mode 100644
index 6335352..0000000
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/FileSystemEntryCacheIndex.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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 legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * 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 legal-notices/CDDLv1_0.txt.
- * 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
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-
-package org.opends.server.extensions;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * This class represents serializable entry cache index structures
- * and supporting data types used for the entry cache persistence.
- * Structurally it should be an inner class of FileSystemEntryCache
- * however due to serialization constraints it has been separated.
- */
-class FileSystemEntryCacheIndex implements Serializable {
-
-  static final long serialVersionUID = 4537634108673038611L;
-
-  /**
-   * The file system entry cache instance this index belongs to.
-   */
-  transient private FileSystemEntryCache fsEntryCacheInstance;
-
-  /**
-   * Backend to checksum/id map for offline state.
-   */
-  public Map<String, Long> offlineState;
-  /**
-   * The mapping between backends and ID to DN maps.
-   */
-  public Map<String, Map<Long, String>> backendMap;
-  /**
-   * The mapping between DNs and IDs.
-   */
-  public Map<String, Long> dnMap;
-
-  /**
-   * Index constructor.
-   * @param fsEntryCacheInstance The File System Entry Cache instance
-   *                             this index is associated with.
-   * @param accessOrder          The ordering mode for the index map
-   *                             {@code true} for access-order,
-   *                             {@code false} for insertion-order.
-   */
-  protected FileSystemEntryCacheIndex(
-    FileSystemEntryCache fsEntryCacheInstance, boolean accessOrder) {
-
-    this.fsEntryCacheInstance = fsEntryCacheInstance;
-
-    offlineState =
-      new ConcurrentHashMap<String, Long>();
-    backendMap =
-      new HashMap<String, Map<Long, String>>();
-    dnMap =
-      new LinkedHashMapRotator<String,Long>(
-      16, (float) 0.75, accessOrder);
-  }
-
-  /**
-   * 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;
-
-    /**
-     * Linked Hash Map Rotator constructor.
-     * @param initialCapacity The initial capacity.
-     * @param loadFactor      The load factor.
-     * @param accessOrder     The ordering mode - {@code true} for
-     *                        access-order, {@code false} for
-     *                        insertion-order.
-     */
-    public LinkedHashMapRotator(int initialCapacity,
-                                float loadFactor,
-                                boolean accessOrder) {
-      super(initialCapacity, loadFactor, accessOrder);
-    }
-
-    /**
-     * This method will get called each time we add a new key/value
-     * pair to the map. The eldest entry will be selected by the
-     * underlying LinkedHashMap implementation based on the access
-     * order configured and will follow either FIFO implementation
-     * by default or LRU implementation if configured so explicitly.
-     * @param  eldest  The least recently inserted entry in the map,
-     *                 or if this is an access-ordered map, the least
-     *                 recently accessed entry.
-     * @return boolean {@code true} if the eldest entry should be
-     *                 removed from the map; {@code false} if it
-     *                 should be retained.
-     */
-    @Override protected boolean removeEldestEntry(Map.Entry eldest) {
-      return fsEntryCacheInstance.removeEldestEntry(eldest);
-    }
-  }
-}
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/DefaultEntryCacheTestCase.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/DefaultEntryCacheTestCase.java
index 071ca6c..8b44383 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/DefaultEntryCacheTestCase.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/DefaultEntryCacheTestCase.java
@@ -28,7 +28,6 @@
 
 
 
-import java.io.File;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.SortedMap;
@@ -38,7 +37,6 @@
 import org.testng.annotations.BeforeClass;
 import org.opends.server.admin.std.meta.*;
 import org.opends.server.admin.std.server.EntryCacheCfg;
-import org.opends.server.admin.std.server.FileSystemEntryCacheCfg;
 import org.opends.server.api.Backend;
 import org.opends.server.api.EntryCache;
 import org.opends.server.core.DirectoryServer;
@@ -63,12 +61,10 @@
   // Entry cache implementations participating in this test.
   private SoftReferenceEntryCache softRefCache = null;
   private FIFOEntryCache fifoCache = null;
-  private FileSystemEntryCache fsCache = null;
 
   // ... and their configuration entries.
   Entry cacheSoftReferenceConfigEntry = null;
   Entry cacheFIFOConfigEntry = null;
-  Entry cacheFSConfigEntry = null;
 
   // The entry cache order map sorted by the cache level.
   private SortedMap<Integer, EntryCache<? extends EntryCacheCfg>>
@@ -78,7 +74,6 @@
   // Dummy test entries for each participating implementation.
   private ArrayList<Entry> testSoftRefEntriesList = null;
   private ArrayList<Entry> testFIFOEntriesList = null;
-  private ArrayList<Entry> testFSEntriesList = null;
 
   /**
    * Initialize the entry cache test.
@@ -127,32 +122,11 @@
       "ds-cfg-enabled: true",
       "ds-cfg-include-filter: uid=fifo*",
       "ds-cfg-include-filter: uid=test2*",
-      "ds-cfg-exclude-filter: uid=test0*");
+      "ds-cfg-include-filter: uid=test0*");
     fifoCache.initializeEntryCache(AdminTestCaseUtils.getConfiguration(
       FIFOEntryCacheCfgDefn.getInstance(), cacheFIFOConfigEntry));
     cacheOrderMap.put(2, fifoCache);
 
-    File cacheDirectory = TestCaseUtils.createTemporaryDirectory("opendj-test");
-    fsCache = new FileSystemEntryCache();
-    cacheFSConfigEntry = TestCaseUtils.makeEntry(
-      "dn: cn=File System,cn=Entry Caches,cn=config",
-      "objectClass: ds-cfg-file-system-entry-cache",
-      "objectClass: ds-cfg-entry-cache",
-      "objectClass: top",
-      "cn: File System",
-      "ds-cfg-cache-level: 3",
-      "ds-cfg-java-class: " +
-      "org.opends.server.extensions.FileSystemEntryCache",
-      "ds-cfg-enabled: true",
-      "ds-cfg-include-filter: uid=fs*",
-      "ds-cfg-include-filter: uid=test3*",
-      "ds-cfg-include-filter: uid=test0*",
-      "ds-cfg-cache-directory: " + cacheDirectory.getAbsolutePath());
-
-    fsCache.initializeEntryCache(AdminTestCaseUtils.getConfiguration(
-      FileSystemEntryCacheCfgDefn.getInstance(), cacheFSConfigEntry));
-    cacheOrderMap.put(3, fsCache);
-
     // Plug all cache implementations into default entry cache.
     final Method[] defaultCacheMethods =
         super.cache.getClass().getDeclaredMethods();
@@ -220,18 +194,6 @@
         "uid: fifo" + Integer.toString(i) + ".user" + Integer.toString(i))
       );
     }
-    testFSEntriesList = new ArrayList<Entry>(super.NUMTESTENTRIES);
-    for(int i = 0; i < super.NUMTESTENTRIES; i++ ) {
-      testFSEntriesList.add(TestCaseUtils.makeEntry(
-        "dn: uid=fs" + Integer.toString(i) + ".user" + Integer.toString(i)
-         + ",ou=test" + Integer.toString(i) + ",o=test",
-        "objectClass: person",
-        "objectClass: inetorgperson",
-        "objectClass: top",
-        "objectClass: organizationalperson",
-        "uid: fs" + Integer.toString(i) + ".user" + Integer.toString(i))
-      );
-    }
 
     // Force GC to make sure we have enough memory for
     // the cache capping constraints to work properly.
@@ -267,12 +229,6 @@
     for (EntryCache<?> entryCache : cacheOrderMap.values()) {
       entryCache.finalizeEntryCache();
     }
-
-    // Remove default FS cache JE environment.
-    FileSystemEntryCacheCfg config = (FileSystemEntryCacheCfg)
-      AdminTestCaseUtils.getConfiguration(EntryCacheCfgDefn.getInstance(),
-      cacheFSConfigEntry);
-    TestCaseUtils.deleteDirectory(new File(config.getCacheDirectory()));
   }
 
 
@@ -455,7 +411,6 @@
     for (int i = 0; i < NUMTESTENTRIES; i++) {
       super.cache.putEntry(testSoftRefEntriesList.get(i), b, i);
       super.cache.putEntry(testFIFOEntriesList.get(i), b, i);
-      super.cache.putEntry(testFSEntriesList.get(i), b, i);
     }
 
     // Ensure all test entries are available via default cache.
@@ -472,12 +427,6 @@
         testFIFOEntriesList.get(0).getName() +
         " in the cache.  Cache contents:" +
         ServerConstants.EOL + cache.toVerboseString());
-      assertNotNull(super.cache.getEntry(
-        testFSEntriesList.get(0).getName()),
-        "Expected to find " +
-        testFSEntriesList.get(0).getName() +
-        " in the cache.  Cache contents:" +
-        ServerConstants.EOL + cache.toVerboseString());
     }
 
     // Ensure all test entries landed on their levels.
@@ -494,12 +443,6 @@
         testFIFOEntriesList.get(0).getName() +
         " in the cache.  Cache contents:" +
         ServerConstants.EOL + cache.toVerboseString());
-      assertNotNull(fsCache.getEntry(
-        testFSEntriesList.get(0).getName()),
-        "Expected to find " +
-        testFSEntriesList.get(0).getName() +
-        " in the cache.  Cache contents:" +
-        ServerConstants.EOL + cache.toVerboseString());
     }
 
     // Clear the cache so that other tests can start from scratch.
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/FileSystemEntryCacheTestCase.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/FileSystemEntryCacheTestCase.java
deleted file mode 100644
index 2706fd0..0000000
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/FileSystemEntryCacheTestCase.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
- * 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 legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * 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 legal-notices/CDDLv1_0.txt.
- * 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
- *
- *
- *      Copyright 2007-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
- */
-package org.opends.server.extensions;
-
-
-
-import java.io.File;
-import java.util.ArrayList;
-import org.opends.server.TestCaseUtils;
-import org.opends.server.admin.server.AdminTestCaseUtils;
-import org.testng.annotations.BeforeClass;
-import org.opends.server.admin.std.meta.*;
-import org.opends.server.admin.std.server.FileSystemEntryCacheCfg;
-import org.opends.server.api.Backend;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.Attributes;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.util.ServerConstants;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterGroups;
-import org.testng.annotations.BeforeGroups;
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-
-
-/**
- * A set of test cases for FileSystem entry cache implementation.
- */
-@Test(groups = "entrycache", sequential=true)
-public class FileSystemEntryCacheTestCase
-       extends CommonEntryCacheTestCase<FileSystemEntryCacheCfg>
-{
-  /**
-   * Configuration entry for this cache.
-   */
-  private Entry cacheConfigEntry;
-
-  /**
-   * Temporary folder to setup dummy JE backend environment in.
-   */
-  private File jeBackendTempDir;
-
-  /**
-   * Utility method to restore default cache configuration.
-   */
-  private void restoreCacheDefaults()
-          throws Exception
-  {
-    // Finalize this cache so it can be reconfigured.
-    super.cache.finalizeEntryCache();
-
-    // Configure this cache back to defaults.
-    super.configuration = AdminTestCaseUtils.getConfiguration(
-      FileSystemEntryCacheCfgDefn.getInstance(), cacheConfigEntry);
-
-    // Initialize the cache.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Make sure the cache is empty.
-    assertNull(cache.toVerboseString(),
-      "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-  }
-
-
-
-  /**
-   * Utility method to configure the cache with LRU access order.
-   */
-  private void setupLRUCache()
-          throws Exception
-  {
-    // Finalize this cache so it can be reconfigured.
-    super.cache.finalizeEntryCache();
-
-    // Configure this cache as LRU.
-    Entry newCacheConfigEntry = cacheConfigEntry.duplicate(true);
-    Attribute cacheConfigTypeAttr =
-      Attributes.create("ds-cfg-cache-type", "LRU");
-    newCacheConfigEntry.addAttribute(cacheConfigTypeAttr, null);
-    super.configuration = AdminTestCaseUtils.getConfiguration(
-        FileSystemEntryCacheCfgDefn.getInstance(), newCacheConfigEntry);
-
-    // Initialize the cache.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Make sure the cache is empty.
-    assertNull(cache.toVerboseString(),
-      "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-  }
-
-
-
-  /**
-   * Utility method to initialize persistent cache.
-   */
-  private void persistentCacheSetup()
-          throws Exception
-  {
-    // Make sure JE directory exist.
-    jeBackendTempDir = TestCaseUtils.createTemporaryDirectory("db-cachetest");
-    String jeDir = jeBackendTempDir.getAbsolutePath();
-
-    // Create dummy JE backend for this test.
-    TestCaseUtils.dsconfig("create-backend", "--backend-name", "cacheTest",
-      "--type", "local-db", "--set", "db-directory:" + jeDir, "--set",
-      "base-dn:o=cachetest", "--set",
-      "writability-mode:enabled", "--set", "enabled:true");
-
-    // Finalize this cache so it can be reconfigured.
-    super.cache.finalizeEntryCache();
-
-    // Configure this cache as persistent cache with
-    // unlimited number of entries.
-    Entry newCacheConfigEntry = cacheConfigEntry.duplicate(true);
-    Attribute cacheConfigPersistAttr =
-      Attributes.create("ds-cfg-persistent-cache", "true");
-    newCacheConfigEntry.addAttribute(cacheConfigPersistAttr, null);
-    Attribute cacheConfigMaxAttr =
-      Attributes.create("ds-cfg-max-entries", Integer.toString(super.MAXENTRIES));
-    newCacheConfigEntry.removeAttribute(cacheConfigMaxAttr, null);
-    super.configuration = AdminTestCaseUtils.getConfiguration(
-        FileSystemEntryCacheCfgDefn.getInstance(), newCacheConfigEntry);
-
-    // Initialize the cache.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Make sure the cache is empty.
-    assertNull(cache.toVerboseString(),
-      "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-  }
-
-
-
-  /**
-   * Utility method to finalize persistent cache.
-   */
-  private void persistentCacheTeardown()
-          throws Exception
-  {
-    // Dummy JE backend cleanup.
-    TestCaseUtils.dsconfig("delete-backend", "--backend-name", "cacheTest");
-    TestCaseUtils.deleteDirectory(jeBackendTempDir);
-
-    // Configure this cache back to defaults.
-    restoreCacheDefaults();
-  }
-
-
-
-  /**
-   * Initialize the entry cache test.
-   *
-   * @throws  Exception  If an unexpected problem occurs.
-   */
-  @BeforeClass
-  public void entryCacheTestInit()
-         throws Exception
-  {
-    // Ensure that the server is running.
-    TestCaseUtils.startServer();
-
-    // Configure this entry cache.
-    File cacheDirectory = TestCaseUtils.createTemporaryDirectory("opendj-test");
-    cacheConfigEntry = TestCaseUtils.makeEntry(
-      "dn: cn=File System,cn=Entry Caches,cn=config",
-      "objectClass: ds-cfg-file-system-entry-cache",
-      "objectClass: ds-cfg-entry-cache",
-      "objectClass: top",
-      "cn: File System",
-      "ds-cfg-cache-level: 1",
-      "ds-cfg-java-class: " +
-      "org.opends.server.extensions.FileSystemEntryCache",
-      "ds-cfg-enabled: true",
-      "ds-cfg-max-entries: " + Integer.toString(super.MAXENTRIES),
-      "ds-cfg-cache-directory: " + cacheDirectory.getAbsolutePath());
-    super.configuration = AdminTestCaseUtils.getConfiguration(
-        FileSystemEntryCacheCfgDefn.getInstance(), cacheConfigEntry);
-
-    // Force GC to make sure we have enough memory for
-    // the cache capping constraints to work properly.
-    System.gc();
-
-    // Initialize the cache.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Make some dummy test entries.
-    super.testEntriesList = new ArrayList<Entry>(super.NUMTESTENTRIES);
-    for(int i = 0; i < super.NUMTESTENTRIES; i++ ) {
-      super.testEntriesList.add(TestCaseUtils.makeEntry(
-        "dn: uid=test" + Integer.toString(i) + ".user" + Integer.toString(i)
-         + ",ou=test" + Integer.toString(i) + ",o=test",
-        "objectClass: person",
-        "objectClass: inetorgperson",
-        "objectClass: top",
-        "objectClass: organizationalperson",
-        "postalAddress: somewhere in Testville" + Integer.toString(i),
-        "street: Under Construction Street" + Integer.toString(i),
-        "l: Testcounty" + Integer.toString(i),
-        "st: Teststate" + Integer.toString(i),
-        "telephoneNumber: +878 8378 8378" + Integer.toString(i),
-        "mobile: +878 8378 8378" + Integer.toString(i),
-        "homePhone: +878 8378 8378" + Integer.toString(i),
-        "pager: +878 8378 8378" + Integer.toString(i),
-        "mail: test" + Integer.toString(i) + ".user" + Integer.toString(i)
-         + "@testdomain.net",
-        "postalCode: 8378" + Integer.toString(i),
-        "userPassword: testpassword" + Integer.toString(i),
-        "description: description for Test" + Integer.toString(i) + "User"
-         + Integer.toString(i),
-        "cn: Test" + Integer.toString(i) + "User" + Integer.toString(i),
-        "sn: User" + Integer.toString(i),
-        "givenName: Test" + Integer.toString(i),
-        "initials: TST" + Integer.toString(i),
-        "employeeNumber: 8378" + Integer.toString(i),
-        "uid: test" + Integer.toString(i) + ".user" + Integer.toString(i))
-      );
-    }
-  }
-
-
-
-  /**
-   * Finalize the entry cache test.
-   *
-   * @throws  Exception  If an unexpected problem occurs.
-   */
-  @AfterClass
-  public void entryCacheTestFini()
-         throws Exception
-  {
-    super.cache.finalizeEntryCache();
-
-    // Remove default FS cache JE environment.
-    FileSystemEntryCacheCfg config = super.configuration;
-    TestCaseUtils.deleteDirectory(new File(config.getCacheDirectory()));
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testContainsEntry()
-         throws Exception
-  {
-    super.testContainsEntry();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testGetEntry1()
-         throws Exception
-  {
-    super.testGetEntry1();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testGetEntry2()
-         throws Exception
-  {
-    super.testGetEntry2();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testGetEntry3()
-         throws Exception
-  {
-    super.testGetEntry3();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testGetEntryID()
-         throws Exception
-  {
-    super.testGetEntryID();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testPutEntry()
-         throws Exception
-  {
-    super.testPutEntry();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testPutEntryIfAbsent()
-         throws Exception
-  {
-    super.testPutEntryIfAbsent();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testRemoveEntry()
-         throws Exception
-  {
-    super.testRemoveEntry();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testClear()
-         throws Exception
-  {
-    super.testClear();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testClearBackend()
-         throws Exception
-  {
-    super.testClearBackend();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testClearSubtree()
-         throws Exception
-  {
-    super.testClearSubtree();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test()
-  @Override
-  public void testHandleLowMemory()
-         throws Exception
-  {
-    super.testHandleLowMemory();
-  }
-
-
-
-  @BeforeGroups(groups = "testFSFIFOCacheConcurrency")
-  public void cacheConcurrencySetup()
-         throws Exception
-  {
-    assertNull(cache.toVerboseString(),
-      "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-  }
-
-
-
-  @AfterGroups(groups = "testFSFIFOCacheConcurrency")
-  public void cacheConcurrencyCleanup()
-         throws Exception
-  {
-    // Clear the cache so that other tests can start from scratch.
-    super.cache.clear();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Test(groups = { "slow", "testFSFIFOCacheConcurrency" },
-        threadPoolSize = 10,
-        invocationCount = 10,
-        // In case of disk based FS.
-        timeOut = 600000)
-  @Override
-  public void testCacheConcurrency()
-         throws Exception
-  {
-    super.testCacheConcurrency();
-  }
-
-
-
-  @BeforeGroups(groups = "testFSLRUCacheConcurrency")
-  public void LRUCacheConcurrencySetup()
-         throws Exception
-  {
-    // Setup LRU cache.
-    setupLRUCache();
-  }
-
-
-
-  @AfterGroups(groups = "testFSLRUCacheConcurrency")
-  public void LRUCacheConcurrencyCleanup()
-         throws Exception
-  {
-    // Configure this cache back to defaults.
-    restoreCacheDefaults();
-  }
-
-
-
-  /**
-   * Tests the entry cache concurrency/threadsafety by executing
-   * core entry cache operations on several threads concurrently
-   * on LRU access order cache.
-   *
-   * @throws  Exception  If an unexpected problem occurs.
-   */
-  @Test(groups = { "slow", "testFSLRUCacheConcurrency" },
-        threadPoolSize = 10,
-        invocationCount = 10,
-        // In case of disk based FS.
-        timeOut = 600000)
-  public void testLRUCacheConcurrency()
-         throws Exception
-  {
-    super.testCacheConcurrency();
-  }
-
-
-
-  /**
-   * Tests FIFO cache rotation on specific number of entries.
-   */
-  @Test(groups = "slow")
-  public void testCacheRotationFIFO()
-         throws Exception
-  {
-    assertNull(cache.toVerboseString(),
-      "Expected empty cache.  " + "Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-
-    // Put some test entries in the cache.
-    Backend b = DirectoryServer.getBackend(DN.valueOf("o=test"));
-    for(int i = 0; i < super.NUMTESTENTRIES; i++ ) {
-      super.cache.putEntry(super.testEntriesList.get(i), b, i);
-    }
-
-    // Make sure first NUMTESTENTRIES - MAXENTRIES got rotated.
-    for(int i = 0; i < (super.NUMTESTENTRIES - super.MAXENTRIES); i++ ) {
-      assertFalse(super.cache.containsEntry(
-        super.testEntriesList.get(i).getName()), "Not expected to find " +
-        super.testEntriesList.get(i).getName() + " in the " +
-        "cache.  Cache contents:" + ServerConstants.EOL +
-        cache.toVerboseString());
-    }
-
-    // Make sure remaining NUMTESTENTRIES are still in the cache.
-    for(int i = (super.NUMTESTENTRIES - super.MAXENTRIES);
-        i < super.NUMTESTENTRIES;
-        i++)
-    {
-      assertTrue(super.cache.containsEntry(
-        super.testEntriesList.get(i).getName()), "Expected to find " +
-        super.testEntriesList.get(i).getName() + " in the " +
-        "cache.  Cache contents:" + ServerConstants.EOL +
-        cache.toVerboseString());
-    }
-
-    // Clear the cache so that other tests can start from scratch.
-    super.cache.clear();
-  }
-
-
-
-  /**
-   * Tests LRU cache rotation on specific number of entries.
-   */
-  @Test(groups = "slow")
-  public void testCacheRotationLRU()
-         throws Exception
-  {
-    // Setup LRU cache.
-    setupLRUCache();
-
-    // Put some test entries in the cache.
-    Backend b = DirectoryServer.getBackend(DN.valueOf("o=test"));
-    for(int i = 0; i < super.NUMTESTENTRIES; i++) {
-      super.cache.putEntry(super.testEntriesList.get(i), b, i);
-      // Sacrifice one cache entry to support rotation.
-      for(int j = 0; j < (super.MAXENTRIES - 1); j++) {
-        // Generate access.
-        super.cache.getEntry(super.testEntriesList.get(j).getName());
-      }
-    }
-
-    // Make sure MAXENTRIES - 1 are still in the cache.
-    for(int i = 0; i < (super.MAXENTRIES - 1); i++) {
-        assertTrue(super.cache.containsEntry(
-          super.testEntriesList.get(i).getName()),
-          "Expected to find " +
-          super.testEntriesList.get(i).getName() + " in the " +
-          "cache.  Cache contents:" + ServerConstants.EOL +
-          cache.toVerboseString());
-    }
-
-    // Plus the last cache entry added.
-    assertTrue(super.cache.containsEntry(
-      super.testEntriesList.get(super.NUMTESTENTRIES - 1).getName()),
-      "Expected to find " +
-      super.testEntriesList.get(super.NUMTESTENTRIES - 1).getName() +
-      " in the cache.  Cache contents:" + ServerConstants.EOL +
-      cache.toVerboseString());
-
-    // And remaining NUMTESTENTRIES - 1 are now rotated.
-    for(int i = (super.MAXENTRIES - 1);
-        i < (super.NUMTESTENTRIES - 1);
-        i++) {
-        assertFalse(super.cache.containsEntry(
-          super.testEntriesList.get(i).getName()),
-          "Not expected to find " +
-          super.testEntriesList.get(i).getName() + " in the " +
-          "cache.  Cache contents:" + ServerConstants.EOL +
-          cache.toVerboseString());
-    }
-
-    // Clear the cache so that other tests can start from scratch.
-    super.cache.clear();
-
-    // Configure this cache back to defaults.
-    restoreCacheDefaults();
-  }
-
-
-
-  /**
-   * Tests cache persistence with consistent backend.
-   */
-  @Test(groups = "slow")
-  public void testCachePersistence()
-         throws Exception
-  {
-    // Setup this test.
-    persistentCacheSetup();
-
-    // Put some test entries in the cache.
-    Backend b = DirectoryServer.getBackend(DN.valueOf("o=cachetest"));
-    for(int i = 0; i < super.NUMTESTENTRIES; i++) {
-      super.cache.putEntry(super.testEntriesList.get(i), b, i);
-    }
-
-    // Should trigger backend checksum.
-    b.finalizeBackend();
-
-    // Finalize and persist this cache.
-    super.cache.finalizeEntryCache();
-
-    // Get cachetest backend online again.
-    b.initializeBackend();
-
-    // Initialize the cache again.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Check that this cache is persistent indeed.
-    for(int i = 0; i < super.NUMTESTENTRIES; i++) {
-      assertTrue(super.cache.containsEntry(
-          super.testEntriesList.get(i).getName()),
-          "Expected to find " +
-          super.testEntriesList.get(i).getName() + " in the " +
-          "cache.  Cache contents:" + ServerConstants.EOL +
-          cache.toVerboseString());
-    }
-
-    // Clear the cache so that other tests can start from scratch.
-    super.cache.clear();
-
-    // Finalize this cache so it can be reconfigured.
-    super.cache.finalizeEntryCache();
-
-    // Clean up.
-    b.finalizeBackend();
-    persistentCacheTeardown();
-  }
-
-
-
-  /**
-   * Tests cache persistence with inconsistent backend.
-   */
-  @Test(groups = "slow")
-  public void testCachePersistenceInconsistent()
-         throws Exception
-  {
-    // Setup this test.
-    persistentCacheSetup();
-
-    // Put some test entries in the cache.
-    Backend b = DirectoryServer.getBackend(DN.valueOf("o=cachetest"));
-    for(int i = 0; i < super.NUMTESTENTRIES; i++) {
-      super.cache.putEntry(super.testEntriesList.get(i), b, i);
-    }
-
-    // Should trigger backend checksum.
-    b.finalizeBackend();
-
-    // Finalize and persist this cache.
-    super.cache.finalizeEntryCache();
-
-    // Get cachetest backend online again.
-    b.initializeBackend();
-
-    // Add dummy entry to cachetest backend to trigger inconsistent
-    // offline state with persistent entry cache.
-    TestCaseUtils.addEntry(
-      "dn: o=cachetest",
-      "objectClass: top",
-      "objectClass: organization");
-
-    // Should trigger backend checksum.
-    b.finalizeBackend();
-
-    // Get cachetest backend online again, now modified.
-    b.initializeBackend();
-
-    // Initialize the cache again.
-    super.cache = new FileSystemEntryCache();
-    super.cache.initializeEntryCache(configuration);
-
-    // Check that this cache is persistent indeed.
-    for(int i = 0; i < super.NUMTESTENTRIES; i++) {
-      assertFalse(super.cache.containsEntry(
-          super.testEntriesList.get(i).getName()),
-          "Not expected to find " +
-          super.testEntriesList.get(i).getName() + " in the " +
-          "cache.  Cache contents:" + ServerConstants.EOL +
-          cache.toVerboseString());
-    }
-
-    // Clear the cache so that other tests can start from scratch.
-    super.cache.clear();
-
-    // Finalize this cache so it can be reconfigured.
-    super.cache.finalizeEntryCache();
-
-    // Clean up.
-    b.finalizeBackend();
-    persistentCacheTeardown();
-  }
-}
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
index 82fc914..e439725 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PreloadEntryCacheTestCase.java
@@ -37,7 +37,6 @@
 import org.testng.annotations.BeforeClass;
 import org.opends.server.admin.std.meta.*;
 import org.opends.server.admin.std.server.EntryCacheCfg;
-import org.opends.server.admin.std.server.FileSystemEntryCacheCfg;
 import org.opends.server.api.Backend;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.Entry;
@@ -81,7 +80,6 @@
    * @throws  Exception  If an unexpected problem occurs.
    */
   @BeforeClass()
-  @SuppressWarnings("unchecked")
   public void preloadEntryCacheTestInit()
          throws Exception
   {
@@ -100,15 +98,15 @@
 
     // Configure the entry cache, use FileSystemEntryCache.
     Entry cacheConfigEntry = TestCaseUtils.makeEntry(
-      "dn: cn=File System,cn=Entry Caches,cn=config",
-      "objectClass: ds-cfg-file-system-entry-cache",
-      "objectClass: ds-cfg-entry-cache",
-      "objectClass: top",
-      "cn: File System",
-      "ds-cfg-cache-level: 1",
-      "ds-cfg-java-class: " +
-      "org.opends.server.extensions.FileSystemEntryCache",
-      "ds-cfg-enabled: true");
+            "dn: cn=Soft Reference,cn=Entry Caches,cn=config",
+            "objectClass: ds-cfg-soft-reference-entry-cache",
+            "objectClass: ds-cfg-entry-cache",
+            "objectClass: top",
+            "cn: Soft Reference",
+            "ds-cfg-cache-level: 1",
+            "ds-cfg-java-class: " +
+            "org.opends.server.extensions.SoftReferenceEntryCache",
+            "ds-cfg-enabled: true");
     configuration = AdminTestCaseUtils.getConfiguration(
       EntryCacheCfgDefn.getInstance(), cacheConfigEntry);
 
@@ -225,11 +223,6 @@
 
     // Sanity in-core restart.
     TestCaseUtils.restartServer();
-
-    // Remove default FS cache JE environment.
-    FileSystemEntryCacheCfg config =
-      (FileSystemEntryCacheCfg) configuration;
-    TestCaseUtils.deleteDirectory(new File(config.getCacheDirectory()));
   }
 
 

--
Gitblit v1.10.0