mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
17.58.2006 5ba5a21b17c663c137efec84151e07821e9db14e
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.

Current version number is 0x01.Any entries that are not of this version will fail decoding since there is only one valid version right now.

NOTE: Any database files created before this revision will be incompatible since they are missing the version byte. Please re-import/add your data.

Fix for issue 573
4 files modified
93 ■■■■ changed files
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java 16 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/ID2Entry.java 33 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/JebFormat.java 31 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/JebMessages.java 13 ●●●●● patch | view | raw | blame | history
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);
    }
    /**
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);
    }
  }
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];
  }
}
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");
  }
}