From 5ba5a21b17c663c137efec84151e07821e9db14e Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Thu, 17 Aug 2006 18:58:55 +0000
Subject: [PATCH] Added an extra byte before the ASN1 encoding of database entries for versioning purposes. Also, error handling mechnisms are also added for handling incompatible version numbers. Some extra catch statements are removed to allow the orginal exception to bubble up to the debug logger.

---
 opends/src/server/org/opends/server/backends/jeb/JebFormat.java      |   31 ++++++++++++++-
 opends/src/server/org/opends/server/backends/jeb/EntryContainer.java |   16 +++-----
 opends/src/server/org/opends/server/messages/JebMessages.java        |   13 ++++++
 opends/src/server/org/opends/server/backends/jeb/ID2Entry.java       |   33 ++++++++++++----
 4 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 33dc69e..30914af 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -1265,6 +1265,11 @@
         Container.transactionAbort(txn);
         throw directoryException;
       }
+      catch (JebException jebException)
+      {
+        Container.transactionAbort(txn);
+        throw jebException;
+      }
       catch (Exception e)
       {
         Container.transactionAbort(txn);
@@ -2246,16 +2251,7 @@
                                                         JebException
     {
       // Read id2entry.
-      try
-      {
-        entry = id2entry.get(txn, entryID);
-      }
-      catch (JebException e)
-      {
-        int msgID = MSGID_JEB_ENTRY_DATABASE_CORRUPT;
-        String message = getMessage(msgID, entryID.toString());
-        throw new JebException(msgID, message);
-      }
+      entry = id2entry.get(txn, entryID);
     }
 
     /**
diff --git a/opends/src/server/org/opends/server/backends/jeb/ID2Entry.java b/opends/src/server/org/opends/server/backends/jeb/ID2Entry.java
index 40e6f71..ce9d480 100644
--- a/opends/src/server/org/opends/server/backends/jeb/ID2Entry.java
+++ b/opends/src/server/org/opends/server/backends/jeb/ID2Entry.java
@@ -248,15 +248,32 @@
     {
       return null;
     }
-    try
+
+    byte[] entryBytes = data.getData();
+    byte entryVersion = JebFormat.getEntryVersion(entryBytes);
+
+    //Try to decode the entry based on the version number. On later versions,
+    //a case could be written to upgrade entries if it is not the current
+    //version
+    switch(entryVersion)
     {
-      return JebFormat.entryFromDatabase(data.getData());
-    }
-    catch (Exception e)
-    {
-      int msgID = MSGID_JEB_ENTRY_DATABASE_CORRUPT;
-      String message = getMessage(msgID, id.toString());
-      throw new JebException(msgID, message);
+      case JebFormat.FORMAT_VERSION :
+        try
+        {
+          return JebFormat.entryFromDatabase(entryBytes);
+        }
+        catch (Exception e)
+        {
+          int msgID = MSGID_JEB_ENTRY_DATABASE_CORRUPT;
+          String message = getMessage(msgID, id.toString());
+          throw new JebException(msgID, message);
+        }
+      //case 0x00                     :
+      //  Call upgrade method? Call 0x00 decode method?
+      default   :
+        int msgID = MSGID_JEB_INCOMPATIBLE_ENTRY_VERSION;
+        String message = getMessage(msgID, id.toString(), entryVersion);
+        throw new JebException(msgID, message);
     }
   }
 
diff --git a/opends/src/server/org/opends/server/backends/jeb/JebFormat.java b/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
index a3beab2..9c5069e 100644
--- a/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
+++ b/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
@@ -64,6 +64,11 @@
        "org.opends.server.backends.je.JebFormat";
 
   /**
+   * The format version used by this class to encode and decode a DatabaseEntry.
+   */
+  public static final byte FORMAT_VERSION = 0x01;
+
+  /**
    * The ASN1 tag for the DatabaseEntry type.
    */
   public static final byte TAG_DATABASE_ENTRY = 0x60;
@@ -89,9 +94,13 @@
   {
     assert debugEnter(CLASS_NAME, "decodeDatabaseEntry", String.valueOf(bytes));
 
+    // Remove version number from the encoded bytes
+    byte[] encodedBytes = new byte[bytes.length - 1];
+    System.arraycopy(bytes, 1, encodedBytes, 0, encodedBytes.length);
+
     // Decode the sequence.
     List<ASN1Element> elements;
-    elements = ASN1Sequence.decodeAsSequence(bytes).elements();
+    elements = ASN1Sequence.decodeAsSequence(encodedBytes).elements();
 
     // Decode the uncompressed size.
     int uncompressedSize;
@@ -292,8 +301,15 @@
     ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
     elements.add(new ASN1Integer(uncompressedSize));
     elements.add(new ASN1OctetString(bytes));
+    byte[] asn1Sequence =
+        new ASN1Sequence(TAG_DATABASE_ENTRY, elements).encode();
 
-    return new ASN1Sequence(TAG_DATABASE_ENTRY, elements).encode();
+    // Prefix version number to the encoded bytes
+    byte[] encodedBytes = new byte[asn1Sequence.length + 1];
+    encodedBytes[0] = FORMAT_VERSION;
+    System.arraycopy(asn1Sequence, 0, encodedBytes, 1, asn1Sequence.length);
+
+    return encodedBytes;
   }
 
   /**
@@ -489,4 +505,15 @@
     return bytes;
   }
 
+   /**
+   * Get the version number of the DatabaseEntry.
+   *
+   * @param bytes The encoded bytes of a DatabaseEntry.
+   * @return The version number.
+   */
+  public static byte getEntryVersion(byte[] bytes)
+  {
+    return bytes[0];
+  }
+
 }
diff --git a/opends/src/server/org/opends/server/messages/JebMessages.java b/opends/src/server/org/opends/server/messages/JebMessages.java
index f026eca..2467bf5 100644
--- a/opends/src/server/org/opends/server/messages/JebMessages.java
+++ b/opends/src/server/org/opends/server/messages/JebMessages.java
@@ -1222,6 +1222,15 @@
 
 
 
+  /**
+   * The message ID of an error indicating the version of DatabaseEntry is
+   * incompatible and can not be decoded.
+   */
+  public static final int MSGID_JEB_INCOMPATIBLE_ENTRY_VERSION =
+       CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 126;
+
+
+
 
   /**
    * Associates a set of generic messages with the message IDs defined in this
@@ -1708,5 +1717,9 @@
                     "The number of threads allocated by the cleaner for log " +
                     "file processing. If the cleaner backlog becomes large, " +
                     "increase this number.");
+    registerMessage(MSGID_JEB_INCOMPATIBLE_ENTRY_VERSION,
+                    "Entry record with ID %s is not compatible with this " +
+                    "version of the backend database. " +
+                    "Entry version: %x");
   }
 }

--
Gitblit v1.10.0