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

Fabio Pistolesi
27.38.2015 f4fc21a222c514860b5232cce2d9f890639f5b5a
OPENDJ-2159 CR-7527 PDB Storage is read-only when using verify-index tool on Windows.

The real problem is the server is killed before flushing has a chance to run and the fact operations for tree creation
do not appear in the journal file. Adding a flag to open tree operations so that we can skip errors on missing trees
while the storage is read only.
Moreover, verify-index was trying to verify indexes already known to be in degraded state, and printing weird stats
about them.
1 files added
21 files modified
273 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/VerifyJob.java 8 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java 58 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AbstractTree.java 4 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java 11 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java 4 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java 30 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Entry.java 7 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java 6 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java 4 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/PersistentCompressedSchema.java 23 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java 23 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/TracedStorage.java 5 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Tree.java 5 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VerifyJob.java 8 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/AccessMode.java 51 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/Storage.java 8 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/WriteableTransaction.java 5 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/DN2IDTest.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/DefaultIndexTest.java 5 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ID2CountTest.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/VerifyJob.java
@@ -138,7 +138,13 @@
          verifyID2Children = true;
          verifyID2Subtree = true;
        }
        attrIndexList.addAll(entryContainer.getAttributeIndexes());
        for (AttributeIndex index : entryContainer.getAttributeIndexes())
        {
          if (index.isTrusted())
          {
            attrIndexList.add(index);
          }
        }
      }
      else
      {
opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
@@ -64,6 +64,7 @@
import org.opends.server.admin.std.server.PDBBackendCfg;
import org.opends.server.api.Backupable;
import org.opends.server.api.DiskSpaceMonitorHandler;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.Importer;
import org.opends.server.backends.pluggable.spi.ReadOnlyStorageException;
@@ -365,12 +366,14 @@
  /** Common interface for internal WriteableTransaction implementations. */
  private interface StorageImpl extends WriteableTransaction, Closeable {
  }
  /** PersistIt implementation of the {@link WriteableTransaction} interface. */
  private final class WriteableStorageImpl implements StorageImpl
  {
    private final Map<TreeName, Exchange> exchanges = new HashMap<>();
    private final String DUMMY_RECORD = "_DUMMY_RECORD_";
    @Override
    public void put(final TreeName treeName, final ByteSequence key, final ByteSequence value)
@@ -462,20 +465,22 @@
    }
    @Override
    public void openTree(final TreeName treeName)
    public void openTree(final TreeName treeName, boolean createOnDemand)
    {
      Exchange ex = null;
      try
      if (createOnDemand)
      {
        ex = getNewExchange(treeName, true);
        openCreateTree(treeName);
      }
      catch (final PersistitException e)
      else
      {
        throw new StorageRuntimeException(e);
      }
      finally
      {
        db.releaseExchange(ex);
        try
        {
          getExchangeFromCache(treeName);
        }
        catch (final PersistitException e)
        {
          throw new StorageRuntimeException(e);
        }
      }
    }
@@ -532,6 +537,28 @@
      }
    }
    private void openCreateTree(final TreeName treeName)
    {
      Exchange ex = null;
      try
      {
        ex = getNewExchange(treeName, true);
        // Work around a problem with forced shutdown right after tree creation.
        // Tree operations are not part of the journal, so force a couple operations to be able to recover.
        ByteString dummyKey = ByteString.valueOf(DUMMY_RECORD);
        put(treeName, dummyKey, ByteString.empty());
        delete(treeName, dummyKey);
      }
      catch (final PersistitException e)
      {
        throw new StorageRuntimeException(e);
      }
      finally
      {
        db.releaseExchange(ex);
      }
    }
    private Exchange getExchangeFromCache(final TreeName treeName) throws PersistitException
    {
      Exchange exchange = exchanges.get(treeName);
@@ -583,8 +610,12 @@
    }
    @Override
    public void openTree(TreeName treeName)
    public void openTree(TreeName treeName, boolean createOnDemand)
    {
      if (createOnDemand)
      {
        throw new ReadOnlyStorageException();
      }
      Exchange ex = null;
      try
      {
@@ -592,7 +623,7 @@
      }
      catch (final TreeNotFoundException e)
      {
        throw new ReadOnlyStorageException();
        // ignore missing trees.
      }
      catch (final PersistitException e)
      {
@@ -648,7 +679,7 @@
  private StorageImpl newStorageImpl() {
    final WriteableStorageImpl writeableStorage = new WriteableStorageImpl();
    return accessMode.equals(AccessMode.READ_ONLY) ? new ReadOnlyStorageImpl(writeableStorage) : writeableStorage;
    return accessMode.isWriteable() ? writeableStorage : new ReadOnlyStorageImpl(writeableStorage);
  }
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
@@ -689,6 +720,7 @@
    dbCfg.setLogFile(new File(backendDirectory, VOLUME_NAME + ".log").getPath());
    dbCfg.setJournalPath(new File(backendDirectory, JOURNAL_NAME).getPath());
    dbCfg.setCheckpointInterval(config.getDBCheckpointerWakeupInterval());
    // Volume is opened read write because recovery will fail if opened read-only
    dbCfg.setVolumeList(asList(new VolumeSpecification(new File(backendDirectory, VOLUME_NAME).getPath(), null,
        BUFFER_SIZE, 4096, Long.MAX_VALUE / BUFFER_SIZE, 2048, true, false, false)));
    final BufferPoolConfiguration bufferPoolCfg = getBufferPoolCfg(dbCfg);
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AbstractTree.java
@@ -46,9 +46,9 @@
  }
  @Override
  public final void open(WriteableTransaction txn) throws StorageRuntimeException
  public final void open(WriteableTransaction txn, boolean createOnDemand) throws StorageRuntimeException
  {
    txn.openTree(name);
    txn.openTree(name, createOnDemand);
    open0(txn);
  }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java
@@ -334,13 +334,14 @@
   * Open the attribute index.
   *
   * @param txn a non null transaction
   * @param createOnDemand true if the tree should be created if it does not exist
   * @throws StorageRuntimeException if an error occurs while opening the index
   */
  void open(WriteableTransaction txn) throws StorageRuntimeException
  void open(WriteableTransaction txn, boolean createOnDemand) throws StorageRuntimeException
  {
    for (Index index : indexIdToIndexes.values())
    {
      index.open(txn);
      index.open(txn, createOnDemand);
    }
    config.addChangeListener(this);
  }
@@ -761,7 +762,7 @@
        {
          for (MatchingRuleIndex addedIndex : addedIndexes.values())
          {
            openIndex(txn, addedIndex, ccr);
            createIndex(txn, addedIndex, ccr);
          }
        }
      });
@@ -805,9 +806,9 @@
    return ccr;
  }
  private static void openIndex(WriteableTransaction txn, MatchingRuleIndex index, ConfigChangeResult ccr)
  private static void createIndex(WriteableTransaction txn, MatchingRuleIndex index, ConfigChangeResult ccr)
  {
    index.open(txn);
    index.open(txn, true);
    if (!index.isTrusted())
    {
      ccr.setAdminActionRequired(true);
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
@@ -54,8 +54,8 @@
import org.opends.server.backends.RebuildConfig;
import org.opends.server.backends.VerifyConfig;
import org.opends.server.backends.pluggable.ImportSuffixCommand.SuffixImportStrategy;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.StorageInUseException;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
import org.opends.server.backends.pluggable.spi.WriteOperation;
@@ -946,7 +946,7 @@
        try
        {
          // The base DN was added.
          EntryContainer ec = rootContainer.openEntryContainer(baseDN, txn);
          EntryContainer ec = rootContainer.openEntryContainer(baseDN, txn, AccessMode.READ_WRITE);
          rootContainer.registerEntryContainer(baseDN, ec);
          DirectoryServer.registerBaseDN(baseDN, this, false);
        }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -73,6 +73,7 @@
import org.opends.server.api.VirtualAttributeProvider;
import org.opends.server.api.plugin.PluginResult.SubordinateDelete;
import org.opends.server.api.plugin.PluginResult.SubordinateModifyDN;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
@@ -217,7 +218,7 @@
          @Override
          public void run(WriteableTransaction txn) throws Exception
          {
            index.open(txn);
            index.open(txn, true);
            if (!index.isTrusted())
            {
              ccr.setAdminActionRequired(true);
@@ -353,7 +354,7 @@
          public void run(WriteableTransaction txn) throws Exception
          {
            VLVIndex vlvIndex = new VLVIndex(cfg, state, storage, EntryContainer.this, txn);
            vlvIndex.open(txn);
            vlvIndex.open(txn, true);
            if(!vlvIndex.isTrusted())
            {
              ccr.setAdminActionRequired(true);
@@ -461,11 +462,13 @@
   * Opens the entryContainer for reading and writing.
   *
   * @param txn a non null transaction
   * @param accessMode specifies how the container has to be opened (read-write or read-only)
   * @throws StorageRuntimeException If an error occurs in the storage.
   * @throws ConfigException if a configuration related error occurs.
   */
  void open(WriteableTransaction txn) throws StorageRuntimeException, ConfigException
  void open(WriteableTransaction txn, AccessMode accessMode) throws StorageRuntimeException, ConfigException
  {
    boolean shouldCreate = accessMode.isWriteable();
    try
    {
      DataConfig entryDataConfig =
@@ -474,18 +477,18 @@
            rootContainer.getCompressedSchema());
      id2entry = new ID2Entry(getIndexName(ID2ENTRY_TREE_NAME), entryDataConfig);
      id2entry.open(txn);
      id2childrenCount.open(txn);
      dn2id.open(txn);
      state.open(txn);
      dn2uri.open(txn);
      id2entry.open(txn, shouldCreate);
      id2childrenCount.open(txn, shouldCreate);
      dn2id.open(txn, shouldCreate);
      state.open(txn, shouldCreate);
      dn2uri.open(txn, shouldCreate);
      for (String idx : config.listBackendIndexes())
      {
        BackendIndexCfg indexCfg = config.getBackendIndex(idx);
        final AttributeIndex index = new AttributeIndex(indexCfg, state, this);
        index.open(txn);
        index.open(txn, shouldCreate);
        if(!index.isTrusted())
        {
          logger.info(NOTE_INDEX_ADD_REQUIRES_REBUILD, index.getName());
@@ -498,8 +501,7 @@
        BackendVLVIndexCfg vlvIndexCfg = config.getBackendVLVIndex(idx);
        VLVIndex vlvIndex = new VLVIndex(vlvIndexCfg, state, storage, this, txn);
        vlvIndex.open(txn);
        vlvIndex.open(txn, shouldCreate);
        if(!vlvIndex.isTrusted())
        {
          logger.info(NOTE_INDEX_ADD_REQUIRES_REBUILD, vlvIndex.getName());
@@ -2664,7 +2666,7 @@
    {
      for(Tree tree : allTrees)
      {
        tree.open(txn);
        tree.open(txn, false);
      }
    }
    catch (Exception e)
@@ -2784,7 +2786,7 @@
    {
      for(Tree tree : allTrees)
      {
        tree.open(txn);
        tree.open(txn, true);
      }
      for (Tree tree : allTrees)
@@ -2830,7 +2832,7 @@
    }
    finally
    {
      tree.open(txn);
      tree.open(txn, true);
    }
    if(logger.isTraceEnabled())
    {
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ID2Entry.java
@@ -231,6 +231,13 @@
    this.dataConfig = dataConfig;
  }
  @Override
  void open0(WriteableTransaction txn) throws StorageRuntimeException
  {
    // Make sure the tree is there and readable, even if the storage is READ_ONLY.
    txn.getRecordCount(getName());
  }
  /**
   * Decodes an entry from its tree representation.
   * <p>
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java
@@ -100,12 +100,12 @@
import org.opends.server.backends.pdb.PDBStorage;
import org.opends.server.backends.pluggable.AttributeIndex.MatchingRuleIndex;
import org.opends.server.backends.pluggable.ImportLDIFReader.EntryInformation;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.Importer;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
import org.opends.server.backends.pluggable.spi.TreeName;
import org.opends.server.backends.pluggable.spi.UpdateFunction;
@@ -640,7 +640,7 @@
      {
        tempDN = baseDN.parent().child(tempDN);
      }
      entryContainer = rootContainer.openEntryContainer(tempDN, txn);
      entryContainer = rootContainer.openEntryContainer(tempDN, txn, AccessMode.READ_WRITE);
      break;
    case INCLUDE_EXCLUDE_BRANCHES:
      break;
@@ -3353,7 +3353,7 @@
          @Override
          public void run(WriteableTransaction txn) throws Exception
          {
            txn.openTree(dnCache);
            txn.openTree(dnCache, true);
          }
        });
      }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java
@@ -87,13 +87,13 @@
import org.opends.server.backends.pluggable.AttributeIndex.MatchingRuleIndex;
import org.opends.server.backends.pluggable.ImportLDIFReader.EntryInformation;
import org.opends.server.backends.pluggable.OnDiskMergeBufferImporter.DNCache;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.Importer;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.SequentialCursor;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
import org.opends.server.backends.pluggable.spi.StorageStatus;
import org.opends.server.backends.pluggable.spi.TreeName;
@@ -1427,7 +1427,7 @@
      {
        tempDN = baseDN.parent().child(tempDN);
      }
      entryContainer = rootContainer.openEntryContainer(tempDN, txn);
      entryContainer = rootContainer.openEntryContainer(tempDN, txn, AccessMode.READ_WRITE);
      break;
    case INCLUDE_EXCLUDE_BRANCHES:
      break;
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/PersistentCompressedSchema.java
@@ -38,6 +38,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.opends.server.api.CompressedSchema;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
@@ -84,6 +85,8 @@
   * @param storage
   *          A reference to the storage in which the trees will be held.
   * @param txn a non null transaction
   * @param accessMode specifies how the storage has been opened (read only or read/write)
   *
   * @throws StorageRuntimeException
   *           If a problem occurs while loading the compressed schema
   *           definitions from the tree.
@@ -91,11 +94,11 @@
   *           If an error occurs while loading and processing the compressed
   *           schema definitions.
   */
  PersistentCompressedSchema(final Storage storage, WriteableTransaction txn)
  PersistentCompressedSchema(final Storage storage, WriteableTransaction txn, AccessMode accessMode)
      throws StorageRuntimeException, InitializationException
  {
    this.storage = storage;
    load(txn);
    load(txn, accessMode.isWriteable());
  }
  /** {@inheritDoc} */
@@ -147,19 +150,11 @@
  }
  /**
   * Loads the compressed schema information from the tree.
   *
   * @throws StorageRuntimeException
   *           If an error occurs while loading the definitions from the tree.
   * @throws InitializationException
   *           If an error occurs while loading and processing the definitions.
   */
  private void load(WriteableTransaction txn) throws StorageRuntimeException, InitializationException
  private void load(WriteableTransaction txn, boolean shouldCreate)
      throws StorageRuntimeException, InitializationException
  {
    txn.openTree(adTreeName);
    txn.openTree(ocTreeName);
    txn.openTree(adTreeName, shouldCreate);
    txn.openTree(ocTreeName, shouldCreate);
    // Cursor through the object class database and load the object class set
    // definitions. At the same time, figure out the highest token value and
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java
@@ -46,10 +46,10 @@
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.PluggableBackendCfg;
import org.opends.server.api.CompressedSchema;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
import org.opends.server.backends.pluggable.spi.StorageStatus;
import org.opends.server.backends.pluggable.spi.WriteOperation;
@@ -123,12 +123,14 @@
  /**
   * Opens the root container.
   *
   * @param accessMode specifies how the container has to be opened (read-write or read-only)
   *
   * @throws StorageRuntimeException
   *           If an error occurs when opening the storage.
   * @throws ConfigException
   *           If an configuration error occurs while opening the storage.
   */
  void open(AccessMode accessMode) throws StorageRuntimeException, ConfigException
  void open(final AccessMode accessMode) throws StorageRuntimeException, ConfigException
  {
    try
    {
@@ -138,8 +140,8 @@
        @Override
        public void run(WriteableTransaction txn) throws Exception
        {
          compressedSchema = new PersistentCompressedSchema(storage, txn);
          openAndRegisterEntryContainers(txn, config.getBaseDN());
          compressedSchema = new PersistentCompressedSchema(storage, txn, accessMode);
          openAndRegisterEntryContainers(txn, config.getBaseDN(), accessMode);
        }
      });
    }
@@ -165,17 +167,18 @@
   *          The base DN of the entry container to open.
   * @param txn
   *          The transaction
   * @param accessMode specifies how the container has to be opened (read-write or read-only)
   * @return The opened entry container.
   * @throws StorageRuntimeException
   *           If an error occurs while opening the entry container.
   * @throws ConfigException
   *           If an configuration error occurs while opening the entry container.
   */
  EntryContainer openEntryContainer(DN baseDN, WriteableTransaction txn)
  EntryContainer openEntryContainer(DN baseDN, WriteableTransaction txn, AccessMode accessMode)
      throws StorageRuntimeException, ConfigException
  {
    EntryContainer ec = new EntryContainer(baseDN, backendId, config, storage, this);
    ec.open(txn);
    ec.open(txn, accessMode);
    return ec;
  }
@@ -204,6 +207,8 @@
   *
   * @param baseDNs
   *          The base DNs of the entry containers to open.
   * @param accessMode specifies how the containers have to be opened (read-write or read-only)
   *
   * @throws StorageRuntimeException
   *           If an error occurs while opening the entry container.
   * @throws InitializationException
@@ -213,13 +218,13 @@
   *           If a configuration error occurs while opening the entry
   *           container.
   */
  private void openAndRegisterEntryContainers(WriteableTransaction txn, Set<DN> baseDNs) throws StorageRuntimeException,
      InitializationException, ConfigException
  private void openAndRegisterEntryContainers(WriteableTransaction txn, Set<DN> baseDNs, AccessMode accessMode)
      throws StorageRuntimeException, InitializationException, ConfigException
  {
    EntryID highestID = null;
    for (DN baseDN : baseDNs)
    {
      EntryContainer ec = openEntryContainer(baseDN, txn);
      EntryContainer ec = openEntryContainer(baseDN, txn, accessMode);
      EntryID id = ec.getHighestEntryID(txn);
      registerEntryContainer(baseDN, ec);
      if (highestID == null || id.compareTo(highestID) > 0)
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/TracedStorage.java
@@ -31,6 +31,7 @@
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.Importer;
import org.opends.server.backends.pluggable.spi.ReadOperation;
@@ -206,9 +207,9 @@
    }
    @Override
    public void openTree(final TreeName name)
    public void openTree(final TreeName name, boolean createOnDemand)
    {
      txn.openTree(name);
      txn.openTree(name, createOnDemand);
      logger.trace("Storage@%s.WriteableTransaction@%s.openTree(%s, %s)",
          storageId(), id(), backendId, name);
    }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Tree.java
@@ -38,15 +38,16 @@
interface Tree
{
  /**
   * Opens a tree. If the provided configuration is transactional,
   * Opens a tree, optionally creating it. If the provided configuration is transactional,
   * a transaction will be created and used to perform the open.
   *
   * @param txn
   *          a non null transaction
   * @param createOnDemand true if the tree should be created if it does not exist
   * @throws StorageRuntimeException
   *           if an error occurs while opening the index.
   */
  void open(WriteableTransaction txn) throws StorageRuntimeException;
  void open(WriteableTransaction txn, boolean createOnDemand) throws StorageRuntimeException;
  /**
   * Deletes this tree and all of its contents.
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VerifyJob.java
@@ -168,7 +168,13 @@
      {
        verifyDN2ID = true;
        verifyID2ChildrenCount = true;
        attrIndexList.addAll(entryContainer.getAttributeIndexes());
        for (AttributeIndex index : entryContainer.getAttributeIndexes())
        {
          if (index.isTrusted())
          {
            attrIndexList.add(index);
          }
        }
      }
      else
      {
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/AccessMode.java
New file
@@ -0,0 +1,51 @@
/*
 * 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 2015 ForgeRock AS
 */
package org.opends.server.backends.pluggable.spi;
/** Defines access modes of a Storage. */
public enum AccessMode {
  /** Constant used to open the Storage in read-only mode; implies missing trees will be ignored. */
  READ_ONLY(false),
  /** Constant used to open the Storage in read-write mode; implies trees will be created if not already present. */
  READ_WRITE(true);
  private boolean readWrite;
  AccessMode(boolean update)
  {
    this.readWrite = update;
  }
  /**
   * Returns if the storage is being opened READ_WRITE.
   *
   * @return true if the storage is being opened READ_WRITE
   */
  public boolean isWriteable()
  {
    return readWrite;
  }
}
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/Storage.java
@@ -41,14 +41,6 @@
public interface Storage extends Closeable
{
  /** Defines access modes of a Storage. */
  public enum AccessMode {
    /** Constant used to open the Storage in read-only mode. */
    READ_ONLY,
    /** Constant used to open the Storage in read-write mode. */
    READ_WRITE;
  }
  /**
   * Starts the import operation.
   *
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/spi/WriteableTransaction.java
@@ -33,12 +33,13 @@
public interface WriteableTransaction extends ReadableTransaction
{
  /**
   * Opens the tree identified by the provided name. The tree is created if it does not already exist.
   * Opens the tree identified by the provided name.
   *
   * @param name
   *          the tree name
   * @param createOnDemand true if the tree should be created if it does not exist
   */
  void openTree(TreeName name);
  void openTree(TreeName name, boolean createOnDemand);
  /**
   * Renames the tree from the old to the new name.
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/DN2IDTest.java
@@ -44,11 +44,11 @@
import org.opends.server.admin.std.server.BackendIndexCfg;
import org.opends.server.admin.std.server.PDBBackendCfg;
import org.opends.server.backends.pdb.PDBStorage;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.SequentialCursor;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.TreeName;
import org.opends.server.backends.pluggable.spi.WriteOperation;
import org.opends.server.backends.pluggable.spi.WriteableTransaction;
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/DefaultIndexTest.java
@@ -45,6 +45,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.DirectoryServerTestCase;
import org.opends.server.backends.pluggable.State.IndexFlag;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
@@ -65,7 +66,7 @@
  public void setUp() {
    txn = new DummyWriteableTransaction();
    index = newIndex("test", 5, EnumSet.of(TRUSTED, COMPACTED));;
    index.open(txn);
    index.open(txn, true);
  }
  @Test
@@ -253,7 +254,7 @@
    }
    @Override
    public void openTree(TreeName name)
    public void openTree(TreeName name, boolean createOnDemand)
    {
      storage.put(name, new TreeMap<ByteString, ByteString>());
    }
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ID2CountTest.java
@@ -45,9 +45,9 @@
import org.opends.server.admin.std.server.BackendIndexCfg;
import org.opends.server.admin.std.server.PDBBackendCfg;
import org.opends.server.backends.pdb.PDBStorage;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.TreeName;
import org.opends.server.backends.pluggable.spi.WriteOperation;
import org.opends.server.backends.pluggable.spi.WriteableTransaction;
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
@@ -59,11 +59,11 @@
import org.opends.server.api.Backend.BackendOperation;
import org.opends.server.api.ClientConnection;
import org.opends.server.backends.VerifyConfig;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.ReadOnlyStorageException;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.TreeName;
import org.opends.server.backends.pluggable.spi.WriteOperation;
import org.opends.server.backends.pluggable.spi.WriteableTransaction;
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java
@@ -41,9 +41,9 @@
import org.opends.server.admin.std.server.PDBBackendCfg;
import org.opends.server.backends.pdb.PDBStorage;
import org.opends.server.backends.pluggable.State.IndexFlag;
import org.opends.server.backends.pluggable.spi.AccessMode;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage.AccessMode;
import org.opends.server.backends.pluggable.spi.TreeName;
import org.opends.server.backends.pluggable.spi.WriteOperation;
import org.opends.server.backends.pluggable.spi.WriteableTransaction;