From 8f4a04835eaa5c44c22116f8f5fde5ad75fa8142 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 19 Dec 2014 09:34:26 +0000
Subject: [PATCH] OPENDJ-1602 New pluggable storage based backend

---
 opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JECompressedSchema.java |  106 ++++++++++++++++++++++-------------------------------
 opendj3-server-dev/build.xml                                                               |    2 -
 opendj3-server-dev/src/server/org/opends/server/backends/pluggable/RootContainer.java      |    9 +---
 3 files changed, 47 insertions(+), 70 deletions(-)

diff --git a/opendj3-server-dev/build.xml b/opendj3-server-dev/build.xml
index 8723447..0ab7ab5 100644
--- a/opendj3-server-dev/build.xml
+++ b/opendj3-server-dev/build.xml
@@ -760,7 +760,6 @@
     <mkdir dir="${build.lib.dir}" />
 
     <javac srcdir="${src.dir}:${admin.src.dir}:${msg.src.dir}:${msg.javagen.dir}:${ads.src.dir}:${quicksetup.src.dir}:${guitools.src.dir}"
-         excludes="${pluggablebackend.pkg}/JECompressedSchema.java"
          destdir="${classes.dir}">
       <classpath>
         <fileset refid="opendj.runtime.jars"/>
@@ -1859,7 +1858,6 @@
     <mkdir dir="${classes.dir}" />
 
     <javac srcdir="${src.dir}:${admin.src.dir}:${msg.src.dir}:${msg.javagen.dir}:${ads.src.dir}:${quicksetup.src.dir}:${guitools.src.dir}"
-        excludes="${pluggablebackend.pkg}/JECompressedSchema.java"
         destdir="${classes.dir}">
       <classpath>
         <fileset refid="opendj.runtime.jars"/>
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JECompressedSchema.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JECompressedSchema.java
index d985a13..bd25bae 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JECompressedSchema.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JECompressedSchema.java
@@ -42,10 +42,12 @@
 import org.opends.server.backends.pluggable.spi.Cursor;
 import org.opends.server.backends.pluggable.spi.Storage;
 import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
+import org.opends.server.backends.pluggable.spi.TreeName;
+import org.opends.server.backends.pluggable.spi.WriteOperation;
+import org.opends.server.backends.pluggable.spi.WriteableStorage;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
-import org.opends.server.util.StaticUtils;
 
 import static org.opends.messages.JebMessages.*;
 
@@ -62,12 +64,13 @@
   /** The name of the database used to store compressed object class set definitions. */
   private static final String DB_NAME_OC = "compressed_object_classes";
 
-  /** The compressed attribute description schema database. */
-  private Database adDatabase;
+  /** The compressed attribute description schema tree. */
+  private static final TreeName adTreeName = new TreeName("compressed_schema", DB_NAME_AD);
+  /** The compressed object class set schema tree. */
+  private static final TreeName ocTreeName = new TreeName("compressed_schema", DB_NAME_OC);
+
   /** The environment in which the databases are held. */
-  private Storage environment;
-  /** The compressed object class set schema database. */
-  private Database ocDatabase;
+  private Storage storage;
 
   private final ByteStringBuilder storeAttributeWriterBuffer = new ByteStringBuilder();
   private final ASN1Writer storeAttributeWriter = ASN1.getWriter(storeAttributeWriterBuffer);
@@ -79,9 +82,10 @@
   /**
    * Creates a new instance of this JE compressed schema manager.
    *
-   * @param environment
+   * @param storage
    *          A reference to the database environment in which the databases
    *          will be held.
+   * @param txn
    * @throws StorageRuntimeException
    *           If a database problem occurs while loading the compressed schema
    *           definitions from the database.
@@ -89,11 +93,11 @@
    *           If an error occurs while loading and processing the compressed
    *           schema definitions.
    */
-  public JECompressedSchema(final Storage environment)
+  public JECompressedSchema(final Storage storage, WriteableStorage txn)
       throws StorageRuntimeException, InitializationException
   {
-    this.environment = environment;
-    load();
+    this.storage = storage;
+    load(txn);
   }
 
 
@@ -104,29 +108,12 @@
    */
   public void close()
   {
-    close0(adDatabase);
-    close0(ocDatabase);
+    storage.closeTree(adTreeName);
+    storage.closeTree(ocTreeName);
 
-    adDatabase = null;
-    ocDatabase = null;
-    environment = null;
+    storage = null;
   }
 
-  private void close0(Database database)
-  {
-    try
-    {
-      database.sync();
-    }
-    catch (final Exception e)
-    {
-      // Ignore.
-    }
-    StaticUtils.close(database);
-  }
-
-
-
   /** {@inheritDoc} */
   @Override
   protected void storeAttribute(final byte[] encodedAttribute,
@@ -143,7 +130,7 @@
         storeAttributeWriter.writeOctetString(option);
       }
       storeAttributeWriter.writeEndSequence();
-      store(adDatabase, encodedAttribute, storeAttributeWriterBuffer);
+      store(adTreeName, encodedAttribute, storeAttributeWriterBuffer);
     }
     catch (final IOException e)
     {
@@ -167,7 +154,7 @@
         storeObjectClassesWriter.writeOctetString(ocName);
       }
       storeObjectClassesWriter.writeEndSequence();
-      store(ocDatabase, encodedObjectClasses, storeObjectClassesWriterBuffer);
+      store(ocTreeName, encodedObjectClasses, storeObjectClassesWriterBuffer);
     }
     catch (final IOException e)
     {
@@ -186,17 +173,15 @@
    * @throws InitializationException
    *           If an error occurs while loading and processing the definitions.
    */
-  private void load() throws StorageRuntimeException, InitializationException
+  private void load(WriteableStorage txn) throws StorageRuntimeException, InitializationException
   {
-    final DatabaseConfig dbConfig = JEBUtils.toDatabaseConfigNoDuplicates(environment);
-
-    adDatabase = environment.openDatabase(null, DB_NAME_AD, dbConfig);
-    ocDatabase = environment.openDatabase(null, DB_NAME_OC, dbConfig);
+    txn.openTree(adTreeName);
+    txn.openTree(ocTreeName);
 
     // Cursor through the object class database and load the object class set
     // definitions. At the same time, figure out the highest token value and
     // initialize the object class counter to one greater than that.
-    final Cursor ocCursor = ocDatabase.openCursor(null);
+    final Cursor ocCursor = txn.openCursor(ocTreeName);
     try
     {
       while (ocCursor.next())
@@ -226,7 +211,7 @@
 
     // Cursor through the attribute description database and load the attribute
     // set definitions.
-    final Cursor adCursor = adDatabase.openCursor(null);
+    final Cursor adCursor = txn.openCursor(adTreeName);
     try
     {
       while (adCursor.next())
@@ -256,45 +241,42 @@
     }
   }
 
-
-
-  private void store(final Database database, final byte[] key, final ByteStringBuilder value) throws DirectoryException
+  private void store(final TreeName treeName, final byte[] key, final ByteStringBuilder value)
+      throws DirectoryException
   {
-    if (!putNoOverwrite(database, key, value))
+    if (!putNoOverwrite(treeName, key, value))
     {
       final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_MULTIPLE_FAILURES.get();
       throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m);
     }
   }
 
-  private boolean putNoOverwrite(final Database database, final byte[] key, final ByteStringBuilder value)
+  private boolean putNoOverwrite(final TreeName treeName, final byte[] key, final ByteStringBuilder value)
       throws DirectoryException
   {
     final ByteString keyEntry = ByteString.wrap(key);
     final ByteString valueEntry = ByteString.wrap(value.getBackingArray(), 0, value.length());
-    for (int i = 0; i < 3; i++)
+    try
     {
-      try
+      storage.write(new WriteOperation()
       {
-        final OperationStatus status = database.putNoOverwrite(null, keyEntry, valueEntry);
-        if (status != SUCCESS)
+        @Override
+        public void run(WriteableStorage txn) throws Exception
         {
-          final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_STATUS.get(status);
-          throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m);
+          if (!txn.putIfAbsent(treeName, keyEntry, valueEntry))
+          {
+            final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_STATUS.get(false);
+            throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m);
+          }
         }
-        return true;
-      }
-      catch (final LockConflictException ce)
-      {
-        continue;
-      }
-      catch (final StorageRuntimeException de)
-      {
-        final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_EX.get(de.getMessage());
-        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, de);
-      }
+      });
+      return true;
     }
-    return false;
+    catch (final Exception e)
+    {
+      final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_EX.get(e.getMessage());
+      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, e);
+    }
   }
 
 }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/RootContainer.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/RootContainer.java
index 9770a7d..6e4286f 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/RootContainer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/RootContainer.java
@@ -44,7 +44,6 @@
 import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
 import org.opends.server.backends.pluggable.spi.WriteOperation;
 import org.opends.server.backends.pluggable.spi.WriteableStorage;
-import org.opends.server.core.DefaultCompressedSchema;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DN;
@@ -94,9 +93,8 @@
   /** The cached value of the next entry identifier to be assigned. */
   private AtomicLong nextid = new AtomicLong(1);
 
-  // FIXME JNR Switch back to a database persisted implementation of CompressedSchema
   /** The compressed schema manager for this backend. */
-  private CompressedSchema compressedSchema;
+  private JECompressedSchema compressedSchema;
 
   private File backendDirectory;
 
@@ -320,7 +318,6 @@
       }
     }
 
-    compressedSchema = new DefaultCompressedSchema();
     try
     {
       storage = new PersistItStorage();
@@ -331,6 +328,7 @@
         @Override
         public void run(WriteableStorage txn) throws Exception
         {
+          compressedSchema = new JECompressedSchema(storage, txn);
           openAndRegisterEntryContainers(txn, config.getBaseDN());
         }
       });
@@ -535,8 +533,7 @@
       }
     }
 
-    // FIXME JNR call close() for a DB stored compressed schema
-    // compressedSchema.close();
+    compressedSchema.close();
     config.removePersistitChangeListener(this);
 
     if (storage != null)

--
Gitblit v1.10.0