From 207cfae7111af06d52afcfab71b2c80b87fe473a Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 12 Aug 2013 15:22:03 +0000
Subject: [PATCH] OPENDJ-1116 Introduce abstraction for the changelog DB
---
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDbEnv.java | 240 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 126 insertions(+), 114 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDbEnv.java b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDbEnv.java
index 3758a13..d0d3e2b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDbEnv.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationDbEnv.java
@@ -27,11 +27,6 @@
*/
package org.opends.server.replication.server;
-import static org.opends.messages.ReplicationMessages.*;
-import static org.opends.server.loggers.ErrorLogger.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import static org.opends.server.util.StaticUtils.*;
-
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;
@@ -39,10 +34,15 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
+import org.opends.server.replication.server.changelog.api.ChangelogException;
import com.sleepycat.je.*;
+import static org.opends.messages.ReplicationMessages.*;
+import static org.opends.server.loggers.ErrorLogger.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
/**
* This class is used to represent a Db environment that can be used
* to create ReplicationDB.
@@ -67,95 +67,99 @@
* @param path Path where the backing files must be created.
* @param replicationServer the ReplicationServer that creates this
* ReplicationDbEnv.
- * @throws DatabaseException If a DatabaseException occurred that prevented
+ * @throws ChangelogException If an Exception occurred that prevented
* the initialization to happen.
- * @throws ReplicationDBException If a replicationServer internal error caused
- * a failure of the replicationServer processing.
*/
public ReplicationDbEnv(String path, ReplicationServer replicationServer)
- throws DatabaseException, ReplicationDBException
+ throws ChangelogException
{
this.replicationServer = replicationServer;
- EnvironmentConfig envConfig = new EnvironmentConfig();
- /* Create the DB Environment that will be used for all
- * the ReplicationServer activities related to the db
- */
- envConfig.setAllowCreate(true);
- envConfig.setTransactional(true);
- envConfig.setConfigParam("je.cleaner.threads", "2");
- envConfig.setConfigParam("je.checkpointer.highPriority", "true");
-
- /*
- * Tests have shown that since the parsing of the Replication log is always
- * done sequentially, it is not necessary to use a large DB cache.
- */
- if (Runtime.getRuntime().maxMemory() > 256 * 1024 * 1024)
+ try
{
- /*
- * If the JVM is reasonably large then we can safely default to bigger
- * read buffers. This will result in more scalable checkpointer and
- * cleaner performance.
- */
- envConfig.setConfigParam("je.cleaner.lookAheadCacheSize",
- String.valueOf(2 * 1024 * 1024));
-
- envConfig.setConfigParam("je.log.iteratorReadSize",
- String.valueOf(2 * 1024 * 1024));
-
- envConfig
- .setConfigParam("je.log.faultReadSize", String.valueOf(4 * 1024));
+ EnvironmentConfig envConfig = new EnvironmentConfig();
/*
- * The cache size must be bigger in order to accommodate the larger
- * buffers - see OPENDJ-943.
+ * Create the DB Environment that will be used for all the
+ * ReplicationServer activities related to the db
*/
- envConfig
- .setConfigParam("je.maxMemory", String.valueOf(16 * 1024 * 1024));
+ envConfig.setAllowCreate(true);
+ envConfig.setTransactional(true);
+ envConfig.setConfigParam("je.cleaner.threads", "2");
+ envConfig.setConfigParam("je.checkpointer.highPriority", "true");
+
+ /*
+ * Tests have shown that since the parsing of the Replication log is
+ * always done sequentially, it is not necessary to use a large DB cache.
+ */
+ if (Runtime.getRuntime().maxMemory() > 256 * 1024 * 1024)
+ {
+ /*
+ * If the JVM is reasonably large then we can safely default to bigger
+ * read buffers. This will result in more scalable checkpointer and
+ * cleaner performance.
+ */
+ envConfig.setConfigParam("je.cleaner.lookAheadCacheSize",
+ String.valueOf(2 * 1024 * 1024));
+ envConfig.setConfigParam("je.log.iteratorReadSize",
+ String.valueOf(2 * 1024 * 1024));
+ envConfig.setConfigParam("je.log.faultReadSize",
+ String.valueOf(4 * 1024));
+
+ /*
+ * The cache size must be bigger in order to accommodate the larger
+ * buffers - see OPENDJ-943.
+ */
+ envConfig.setConfigParam("je.maxMemory",
+ String.valueOf(16 * 1024 * 1024));
+ }
+ else
+ {
+ /*
+ * Use 5M so that the replication can be used with 64M total for the
+ * JVM.
+ */
+ envConfig.setConfigParam("je.maxMemory",
+ String.valueOf(5 * 1024 * 1024));
+ }
+
+ // Since records are always added at the end of the Replication log and
+ // deleted at the beginning of the Replication log, this should never
+ // cause any deadlock.
+ envConfig.setTxnTimeout(0, TimeUnit.SECONDS);
+ envConfig.setLockTimeout(0, TimeUnit.SECONDS);
+
+ // Since replication provides durability, we can reduce the DB durability
+ // level so that we are immune to application / JVM crashes.
+ envConfig.setDurability(Durability.COMMIT_WRITE_NO_SYNC);
+
+ dbEnvironment = new Environment(new File(path), envConfig);
+
+ /*
+ * One database is created to store the update from each LDAP server in
+ * the topology. The database "changelogstate" is used to store the list
+ * of all the servers that have been seen in the past.
+ */
+ DatabaseConfig dbConfig = new DatabaseConfig();
+ dbConfig.setAllowCreate(true);
+ dbConfig.setTransactional(true);
+
+ stateDb = dbEnvironment.openDatabase(null, "changelogstate", dbConfig);
+ start();
}
- else
+ catch (RuntimeException e)
{
- /*
- * Use 5M so that the replication can be used with 64M total for the JVM.
- */
- envConfig.setConfigParam("je.maxMemory", String.valueOf(5 * 1024 * 1024));
+ throw new ChangelogException(e);
}
-
- // Since records are always added at the end of the Replication log and
- // deleted at the beginning of the Replication log, this should never
- // cause any deadlock.
- envConfig.setTxnTimeout(0, TimeUnit.SECONDS);
- envConfig.setLockTimeout(0, TimeUnit.SECONDS);
-
- // Since replication provides durability, we can reduce the DB durability
- // level so that we are immune to application / JVM crashes.
- envConfig.setDurability(Durability.COMMIT_WRITE_NO_SYNC);
-
- dbEnvironment = new Environment(new File(path), envConfig);
-
- /*
- * One database is created to store the update from each LDAP
- * server in the topology.
- * The database "changelogstate" is used to store the list of all
- * the servers that have been seen in the past.
- */
- DatabaseConfig dbConfig = new DatabaseConfig();
- dbConfig.setAllowCreate(true);
- dbConfig.setTransactional(true);
-
- stateDb = dbEnvironment.openDatabase(null, "changelogstate", dbConfig);
- start();
}
/**
* Read the list of known servers from the database and start dbHandler
* for each of them.
*
- * @throws DatabaseException in case of underlying DatabaseException
- * @throws ReplicationDBException when the information from the database
- * cannot be decoded correctly.
+ * @throws ChangelogException in case of underlying Exception
*/
- private void start() throws DatabaseException, ReplicationDBException
+ private void start() throws ChangelogException, DatabaseException
{
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
@@ -168,23 +172,15 @@
}
finally
{
- try
- {
- cursor.close();
- }
- catch (Exception ignored)
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, ignored);
- }
+ close(cursor);
}
}
private void readDomainBaseDNGenerationIDRecords(DatabaseEntry key,
- DatabaseEntry data, Cursor cursor) throws ReplicationDBException
+ DatabaseEntry data, Cursor cursor) throws ChangelogException,
+ DatabaseException
{
- /*
- * Get the domain base DN/ generationIDs records
- */
+ // Get the domain base DN/ generationIDs records
OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
while (status == OperationStatus.SUCCESS)
{
@@ -214,11 +210,10 @@
}
private void readServerIdDomainBaseDNRecords(DatabaseEntry key,
- DatabaseEntry data, Cursor cursor) throws ReplicationDBException
+ DatabaseEntry data, Cursor cursor) throws ChangelogException,
+ DatabaseException
{
- /*
- * Get the server Id / domain base DN records
- */
+ // Get the server Id / domain base DN records
OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
while (status == OperationStatus.SUCCESS)
{
@@ -252,7 +247,7 @@
}
}
- private int toInt(String data) throws ReplicationDBException
+ private int toInt(String data) throws ChangelogException
{
try
{
@@ -261,13 +256,13 @@
{
// should never happen
// TODO: i18n
- throw new ReplicationDBException(Message
- .raw("replicationServer state database has a wrong format: "
- + e.getLocalizedMessage() + "<" + data + ">"));
+ throw new ChangelogException(Message.raw(
+ "replicationServer state database has a wrong format: "
+ + e.getLocalizedMessage() + "<" + data + ">"));
}
}
- private long toLong(String data) throws ReplicationDBException
+ private long toLong(String data) throws ChangelogException
{
try
{
@@ -277,13 +272,13 @@
{
// should never happen
// TODO: i18n
- throw new ReplicationDBException(Message
- .raw("replicationServer state database has a wrong format: "
- + e.getLocalizedMessage() + "<" + data + ">"));
+ throw new ChangelogException(Message.raw(
+ "replicationServer state database has a wrong format: "
+ + e.getLocalizedMessage() + "<" + data + ">"));
}
}
- private String toString(byte[] data) throws ReplicationDBException
+ private String toString(byte[] data) throws ChangelogException
{
try
{
@@ -293,7 +288,7 @@
{
// should never happens
// TODO: i18n
- throw new ReplicationDBException(Message.raw("need UTF-8 support"));
+ throw new ChangelogException(Message.raw("need UTF-8 support"));
}
}
@@ -305,10 +300,10 @@
* @param baseDn The baseDn that identifies the domain.
* @param generationId The generationId associated to this domain.
* @return the Database.
- * @throws DatabaseException in case of underlying Exception.
+ * @throws ChangelogException in case of underlying Exception.
*/
public Database getOrAddDb(int serverId, String baseDn, long generationId)
- throws DatabaseException
+ throws ChangelogException
{
if (debugEnabled())
TRACER.debugInfo("ReplicationDbEnv.getOrAddDb() " +
@@ -337,6 +332,10 @@
putInStateDBIfNotExist(genIdKey, genIdData);
return db;
}
+ catch (RuntimeException e)
+ {
+ throw new ChangelogException(e);
+ }
catch (UnsupportedEncodingException e)
{
// can't happen
@@ -345,7 +344,7 @@
}
private void putInStateDBIfNotExist(String keyString, String dataString)
- throws UnsupportedEncodingException
+ throws UnsupportedEncodingException, RuntimeException
{
byte[] byteId = keyString.getBytes("UTF-8");
byte[] dataByteId = dataString.getBytes("UTF-8");
@@ -378,11 +377,18 @@
* Creates a new transaction.
*
* @return the transaction.
- * @throws DatabaseException in case of underlying database Exception.
+ * @throws ChangelogException in case of underlying exception
*/
- public Transaction beginTransaction() throws DatabaseException
+ public Transaction beginTransaction() throws ChangelogException
{
- return dbEnvironment.beginTransaction(null, null);
+ try
+ {
+ return dbEnvironment.beginTransaction(null, null);
+ }
+ catch (RuntimeException e)
+ {
+ throw new ChangelogException(e);
+ }
}
/**
@@ -478,7 +484,7 @@
+ this.replicationServer.getMonitorInstanceName() + " "
+ methodInvocation + " succeeded " + status);
}
- catch (DatabaseException dbe)
+ catch (RuntimeException dbe)
{
// Abort the txn and propagate the Exception to the caller
txn.abort();
@@ -491,7 +497,7 @@
{
// can't happen
}
- catch (DatabaseException dbe)
+ catch (RuntimeException dbe)
{
// FIXME can actually happen (see catch above)
// what should we do about it?
@@ -514,7 +520,7 @@
txn.commit(Durability.COMMIT_WRITE_NO_SYNC);
txn = null;
}
- catch (DatabaseException e)
+ catch (RuntimeException e)
{
MessageBuilder mb = new MessageBuilder();
mb.append(ERR_ERROR_CLEARING_DB.get(databaseName,
@@ -540,10 +546,9 @@
* TODO:ECL how to manage compatibility of this db with new domains
* added or removed ?
* @return the retrieved or created db.
- * @throws DatabaseException when a problem occurs.
+ * @throws ChangelogException when a problem occurs.
*/
- public Database getOrCreateDraftCNDb()
- throws DatabaseException
+ public Database getOrCreateDraftCNDb() throws ChangelogException
{
String stringId = "draftcndb";
@@ -553,6 +558,13 @@
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
- return dbEnvironment.openDatabase(null, stringId, dbConfig);
+ try
+ {
+ return dbEnvironment.openDatabase(null, stringId, dbConfig);
+ }
+ catch (RuntimeException e)
+ {
+ throw new ChangelogException(e);
+ }
}
}
--
Gitblit v1.10.0