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

Nicolas Capponi
17.40.2014 dbc982944cd13543eaa810c6eb0b78a7c2524d86
opends/src/server/org/opends/server/replication/server/changelog/file/LogFile.java
@@ -26,6 +26,7 @@
package org.opends.server.replication.server.changelog.file;
import static org.opends.messages.ReplicationMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.io.BufferedWriter;
@@ -33,6 +34,7 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.forgerock.util.Reject;
import org.opends.messages.Message;
@@ -103,7 +105,15 @@
    this.isWriteEnabled = isWriteEnabled;
    createLogFileIfNotExists();
    writer = isWriteEnabled ? BlockLogWriter.newWriter(new LogWriter(logfile), parser) : null;
    if (isWriteEnabled)
    {
      ensureLogFileIsValid(parser);
      writer = BlockLogWriter.newWriter(new LogWriter(logfile), parser);
    }
    else
    {
      writer = null;
    }
    readerPool = new LogReaderPool<K, V>(logfile, parser);
  }
@@ -184,6 +194,44 @@
  }
  /**
   * Ensure that log file is not corrupted, by checking it is valid and cleaning
   * the end of file if necessary, to remove a partially written record.
   * <p>
   * If log file is cleaned to remove a partially written record, then a message
   * is logged for information.
   *
   * @throws ChangelogException
   *           If an error occurs or if log file is corrupted and can't be
   *           cleaned
   */
  private void ensureLogFileIsValid(final RecordParser<K, V> parser) throws ChangelogException
  {
    BlockLogReader<K, V> reader = null;
    try
    {
      final RandomAccessFile readerWriter = new RandomAccessFile(logfile, "rws");
      reader = BlockLogReader.newReader(logfile, readerWriter, parser) ;
      final long lastValidPosition = reader.checkLogIsValid();
      if (lastValidPosition != -1)
      {
          // truncate the file to point where last valid record has been read
          readerWriter.setLength(lastValidPosition);
          logError(INFO_CHANGELOG_LOG_FILE_RECOVERED.get(logfile.getPath()));
      }
    }
    catch (IOException e)
    {
      throw new ChangelogException(ERR_CHANGELOG_UNABLE_TO_RECOVER_LOG_FILE.get(
          logfile.getPath(),
          StaticUtils.stackTraceToSingleLineString(e)));
    }
    finally
    {
      StaticUtils.close(reader);
    }
  }
  /**
   * Add the provided record at the end of this log.
   * <p>
   * In order to ensure that record is written out of buffers and persisted