opends/src/messages/messages/replication.properties
@@ -62,8 +62,6 @@ MILD_ERR_UNKNOWN_TYPE_7=Unknown operation type : %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=Internal Error : Operation %s \ change number %s was not found in pending list MILD_ERR_COULD_NOT_INITIALIZE_DB_10=The replication server failed to start because the \ database %s could not be opened MILD_ERR_COULD_NOT_READ_DB_11=The replication server failed to start because the database \ %s could not be read : %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=An Exception was caught while \ opends/src/messages/messages/replication_de.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=Der Replikationsserver konnte nicht gestartet werden: Verbindung zu Listen-Port %d nicht m\u00f6glich. Fehler: %s MILD_ERR_UNKNOWN_TYPE_7=Unbekannter Vorgangstyp: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=Interner Fehler: Vorgang %s, \u00c4nderungsnummer %s, wurde nicht in der Liste f\u00fcr ausstehende Elemente gefunden MILD_ERR_COULD_NOT_INITIALIZE_DB_10=Der Replikationsserver konnte nicht gestartet werden, da die Datenbank %s nicht ge\u00f6ffnet werden konnte MILD_ERR_COULD_NOT_READ_DB_11=Der Replikationsserver konnte nicht gestartet werden, da die Datenbank %s nicht gelesen werden konnte: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=Beim Wiederholen von Vorgang %s ist ein Ausnahmefehler aufgetreten: %s DEBUG_ERROR_UPDATING_RUV_14=Fehler %s bei der Aktualisierung des Serverstatus %s : %s Basis-DN : %s opends/src/messages/messages/replication_es.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=Error al iniciar Replication Server: no se pudo enlazar con el puerto de escucha: %d. Error: %s MILD_ERR_UNKNOWN_TYPE_7=Tipo de operaci\u00f3n desconocido: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=Error interno : el n\u00famero de cambio %s de la operaci\u00f3n %s no se encontr\u00f3 en la lista de pendientes MILD_ERR_COULD_NOT_INITIALIZE_DB_10=Error al iniciar el servidor de repetici\u00f3n porque no se pudo abrir la base de datos %s MILD_ERR_COULD_NOT_READ_DB_11=Error al iniciar el servidor de repetici\u00f3n porque no se pudo leer la base de datos %s: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=Se obtuvo una excepci\u00f3n durante la reproducci\u00f3n de la operaci\u00f3n %s: %s DEBUG_ERROR_UPDATING_RUV_14=Error %s al actualizar el estado del servidor %s: ND de base de %s : %s opends/src/messages/messages/replication_fr.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=\u00c9chec du d\u00e9marrage du serveur de r\u00e9plication : impossible de cr\u00e9er une liaison au port d'\u00e9coute : %d. Erreur : %s MILD_ERR_UNKNOWN_TYPE_7=Type d'op\u00e9ration inconnu : %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=Erreur interne : le num\u00e9ro de modification %s de l'op\u00e9ration %s est introuvable dans la liste en attente MILD_ERR_COULD_NOT_INITIALIZE_DB_10=L'\u00e9chec du d\u00e9marrage du serveur de r\u00e9plication, car la base de donn\u00e9es %s n'a pas pu \u00eatre ouverte MILD_ERR_COULD_NOT_READ_DB_11=\u00c9chec du d\u00e9marrage du serveur de r\u00e9plication, car la base de donn\u00e9es %s n'a pas pu \u00eatre lue : %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=Une exception a \u00e9t\u00e9 d\u00e9tect\u00e9e lors de la relecture de l'op\u00e9ration %s : %s DEBUG_ERROR_UPDATING_RUV_14=Erreur %s lors de la mise \u00e0 jour de l'\u00e9tat du serveur %s\u00a0: DN de base %s\u00a0: %s opends/src/messages/messages/replication_ja.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306e\u8d77\u52d5\u306b\u5931\u6557\u3057\u307e\u3057\u305f: \u5f85\u6a5f\u30dd\u30fc\u30c8 %d \u306b\u30d0\u30a4\u30f3\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30a8\u30e9\u30fc: %s MILD_ERR_UNKNOWN_TYPE_7=\u4e0d\u660e\u306a\u64cd\u4f5c\u30bf\u30a4\u30d7: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=\u5185\u90e8\u30a8\u30e9\u30fc: \u64cd\u4f5c %s \u306e\u5909\u66f4\u756a\u53f7 %s \u304c\u4fdd\u7559\u4e2d\u306e\u30ea\u30b9\u30c8\u306b\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f MILD_ERR_COULD_NOT_INITIALIZE_DB_10=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 %s \u3092\u958b\u3051\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306e\u8d77\u52d5\u306b\u5931\u6557\u3057\u307e\u3057\u305f MILD_ERR_COULD_NOT_READ_DB_11=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 %s \u3092\u8aad\u307f\u53d6\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30ec\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b5\u30fc\u30d0\u30fc\u306e\u8d77\u52d5\u306b\u5931\u6557\u3057\u307e\u3057\u305f: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=\u64cd\u4f5c %s \u306e\u518d\u5b9f\u884c\u4e2d\u306b\u4f8b\u5916\u304c\u30ad\u30e3\u30c3\u30c1\u3055\u308c\u307e\u3057\u305f: %s DEBUG_ERROR_UPDATING_RUV_14=\u30b5\u30fc\u30d0\u30fc\u306e\u72b6\u614b %2$s \u3092\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc %1$s \u304c\u767a\u751f\u3057\u307e\u3057\u305f: %3$s \u30d9\u30fc\u30b9 DN: %4$s opends/src/messages/messages/replication_ko.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=\ubcf5\uc81c \uc11c\ubc84\ub97c \uc2dc\uc791\ud558\uc9c0 \ubabb\ud568: \uc218\uc2e0 \ud3ec\ud2b8\uc5d0 \ubc14\uc778\ub4dc\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4: %d. \uc624\ub958: %s MILD_ERR_UNKNOWN_TYPE_7=\uc54c \uc218 \uc5c6\ub294 \uc791\uc5c5 \uc720\ud615: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=\ub0b4\ubd80 \uc624\ub958: \uc791\uc5c5 %s \ubcc0\uacbd \ubc88\ud638 %s\uc774(\uac00) \ubcf4\ub958 \ubaa9\ub85d\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4. MILD_ERR_COULD_NOT_INITIALIZE_DB_10=\ub370\uc774\ud130\ubca0\uc774\uc2a4 %s\uc744(\ub97c) \uc5f4\uc9c0 \ubabb\ud588\uae30 \ub54c\ubb38\uc5d0 \ubcf5\uc81c \uc11c\ubc84\ub97c \uc2dc\uc791\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4. MILD_ERR_COULD_NOT_READ_DB_11=\ub370\uc774\ud130\ubca0\uc774\uc2a4 %s\uc744(\ub97c) \uc77d\uc9c0 \ubabb\ud588\uae30 \ub54c\ubb38\uc5d0 \ubcf5\uc81c \uc11c\ubc84\ub97c \uc2dc\uc791\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=%s \uc791\uc5c5\uc744 \uc7ac\uc0dd\ud558\ub294 \ub3d9\uc548 \uc608\uc678\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4: %s DEBUG_ERROR_UPDATING_RUV_14=\uc11c\ubc84 \uc0c1\ud0dc %2$s\uc744(\ub97c) \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \ub3d9\uc548 %1$s \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4: %3$s \uae30\ubcf8 dn : %4$s opends/src/messages/messages/replication_zh_CN.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=\u590d\u5236\u670d\u52a1\u5668\u542f\u52a8\u5931\u8d25\uff1a\u65e0\u6cd5\u7ed1\u5b9a\u5230\u4fa6\u542c\u7aef\u53e3: %d\u3002\u9519\u8bef: %s MILD_ERR_UNKNOWN_TYPE_7=\u672a\u77e5\u64cd\u4f5c\u7c7b\u578b: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=\u5185\u90e8\u9519\u8bef\uff1a\u5728\u5f85\u5904\u7406\u64cd\u4f5c\u5217\u8868\u4e2d\u627e\u4e0d\u5230\u64cd\u4f5c %s \u66f4\u6539\u53f7 %s MILD_ERR_COULD_NOT_INITIALIZE_DB_10=\u590d\u5236\u670d\u52a1\u5668\u542f\u52a8\u5931\u8d25\uff0c\u56e0\u4e3a\u65e0\u6cd5\u6253\u5f00\u6570\u636e\u5e93 %s MILD_ERR_COULD_NOT_READ_DB_11=\u590d\u5236\u670d\u52a1\u5668\u542f\u52a8\u5931\u8d25\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bfb\u53d6\u6570\u636e\u5e93 %s: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=\u5728\u91cd\u653e\u64cd\u4f5c %s \u65f6\u6355\u83b7\u5230\u5f02\u5e38: %s DEBUG_ERROR_UPDATING_RUV_14=\u5728\u66f4\u65b0\u670d\u52a1\u5668\u72b6\u6001 %2$s \u65f6\u51fa\u73b0\u9519\u8bef %1$s: %3$s \u57fa DN: %4$s opends/src/messages/messages/replication_zh_TW.properties
@@ -58,7 +58,6 @@ MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=\u8907\u88fd\u4f3a\u670d\u5668\u7121\u6cd5\u555f\u52d5: \u7121\u6cd5\u9023\u7d50\u81f3\u5075\u807d\u9023\u63a5\u57e0: %d\u3002\u932f\u8aa4: %s MILD_ERR_UNKNOWN_TYPE_7=\u4f5c\u696d\u985e\u578b\u4e0d\u660e: %s MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=\u5167\u90e8\u932f\u8aa4: \u5728\u64f1\u7f6e\u6e05\u55ae\u4e2d\u627e\u4e0d\u5230\u4f5c\u696d %s \u8b8a\u66f4\u865f\u78bc %s MILD_ERR_COULD_NOT_INITIALIZE_DB_10=\u8907\u88fd\u4f3a\u670d\u5668\u7121\u6cd5\u555f\u52d5\uff0c\u56e0\u70ba\u8cc7\u6599\u5eab %s \u7121\u6cd5\u958b\u555f MILD_ERR_COULD_NOT_READ_DB_11=\u8907\u88fd\u4f3a\u670d\u5668\u7121\u6cd5\u555f\u52d5\uff0c\u56e0\u70ba\u7121\u6cd5\u8b80\u53d6\u8cc7\u6599\u5eab %s: %s MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=\u91cd\u65b0\u57f7\u884c\u4f5c\u696d %s \u6642\u767c\u751f\u7570\u5e38: %s DEBUG_ERROR_UPDATING_RUV_14=\u66f4\u65b0\u4f3a\u670d\u5668\u72c0\u614b %2$s \u6642\u767c\u751f\u932f\u8aa4 %1$s: %3$s\uff0c\u57fa\u5e95 dn: %4$s opends/src/server/org/opends/server/replication/server/DbHandler.java
@@ -27,10 +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.util.StaticUtils.*; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; @@ -45,12 +41,15 @@ import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.protocol.UpdateMsg; import org.opends.server.replication.server.ReplicationDB.ReplServerDBCursor; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.Attribute; import org.opends.server.types.Attributes; import org.opends.server.types.InitializationException; import org.opends.server.util.TimeThread; import com.sleepycat.je.DatabaseException; import static org.opends.messages.ReplicationMessages.*; import static org.opends.server.loggers.ErrorLogger.*; import static org.opends.server.util.StaticUtils.*; /** * This class is used for managing the replicationServer database for each @@ -136,12 +135,12 @@ * @param dbenv the Database Env to use to create the ReplicationServer DB. * server for this domain. * @param queueSize The queueSize to use when creating the dbHandler. * @throws DatabaseException If a database problem happened * @throws ChangelogException If a database problem happened */ public DbHandler( int id, String baseDn, ReplicationServer replicationServer, ReplicationDbEnv dbenv, int queueSize) throws DatabaseException throws ChangelogException { this.replicationServer = replicationServer; serverId = id; @@ -250,14 +249,11 @@ */ public long getChangesCount() { try if (lastChange != null && firstChange != null) { return lastChange.getSeqnum() - firstChange.getSeqnum() + 1; } catch (Exception e) { return 0; } return 0; } /** @@ -271,12 +267,10 @@ * managed by this dbHandler and starting at the position defined * by a given changeNumber. * * @throws DatabaseException if a database problem happened. * @throws Exception If there is no other change to push after change * with changeNumber number. * @throws ChangelogException if a database problem happened. */ public ReplicationIterator generateIterator(ChangeNumber changeNumber) throws DatabaseException, Exception throws ChangelogException { if (changeNumber == null) { @@ -332,7 +326,8 @@ try { wait(); } catch (Exception e) } catch (InterruptedException e) { /* do nothing */} } } @@ -418,9 +413,9 @@ /** * Trim old changes from this replicationServer database. * @throws DatabaseException In case of database problem. * @throws ChangelogException In case of database problem. */ private void trim() throws DatabaseException, Exception private void trim() throws ChangelogException { if (trimAge == 0) { @@ -476,7 +471,7 @@ } cursor.close(); } catch (Exception e) catch (ChangelogException e) { // mark shutdown for this db so that we don't try again to // stop it from cursor.close() or methods called by cursor.close() @@ -602,12 +597,10 @@ /** * Clear the changes from this DB (from both memory cache and DB storage). * @throws DatabaseException When an exception occurs while removing the * @throws ChangelogException When an exception occurs while removing the * changes from the DB. * @throws Exception When an exception occurs while accessing a resource * from the DB. */ public void clear() throws DatabaseException, Exception public void clear() throws ChangelogException { synchronized(flushLock) { opends/src/server/org/opends/server/replication/server/DraftCNDB.java
@@ -27,6 +27,19 @@ */ package org.opends.server.replication.server; import java.io.Closeable; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.DebugLogLevel; import com.sleepycat.je.*; import static com.sleepycat.je.LockMode.*; import static com.sleepycat.je.OperationStatus.*; @@ -35,16 +48,6 @@ import static org.opends.server.loggers.debug.DebugLogger.*; import static org.opends.server.util.StaticUtils.*; import java.io.Closeable; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.opends.messages.MessageBuilder; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.types.DebugLogLevel; import com.sleepycat.je.*; /** * This class implements the interface between the underlying database * and the dbHandler class. @@ -53,6 +56,8 @@ public class DraftCNDB { private static final DebugTracer TRACER = getTracer(); private static final int DATABASE_EMPTY = 0; private Database db = null; private ReplicationDbEnv dbenv = null; private ReplicationServer replicationServer; @@ -61,27 +66,23 @@ * The lock used to provide exclusive access to the thread that close the db * (shutdown or clear). */ private ReentrantReadWriteLock dbCloseLock; private final ReadWriteLock dbCloseLock = new ReentrantReadWriteLock(true); /** * Creates a new database or open existing database that will be used * to store and retrieve changes from an LDAP server. * @param replicationServer The ReplicationServer that needs to be shutdown. * @param dbenv The Db environment to use to create the db. * @throws DatabaseException If a database problem happened. * @throws ChangelogException If a database problem happened. */ public DraftCNDB( ReplicationServer replicationServer, ReplicationDbEnv dbenv) throws DatabaseException public DraftCNDB(ReplicationServer replicationServer, ReplicationDbEnv dbenv) throws ChangelogException { this.dbenv = dbenv; this.replicationServer = replicationServer; // Get or create the associated ReplicationServerDomain and Db. db = dbenv.getOrCreateDraftCNDb(); dbCloseLock = new ReentrantReadWriteLock(true); } /** @@ -101,8 +102,7 @@ try { DatabaseEntry key = new ReplicationDraftCNKey(draftCN); DatabaseEntry data = new DraftCNData( value, domainBaseDN, changeNumber); DatabaseEntry data = new DraftCNData(value, domainBaseDN, changeNumber); // Use a transaction so that we can override durability. Transaction txn = null; @@ -121,24 +121,40 @@ } finally { if (txn != null) { // No effect if txn has committed. try { txn.abort(); } catch (Exception e) { // Ignored. } } abort(txn); dbCloseLock.readLock().unlock(); } } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } catch (ChangelogException e) { replicationServer.handleUnexpectedChangelogException(e); } } /** * Aborts the current transaction. It has no effect if the transaction has * committed. * * @param txn * the transaction to abort */ private static void abort(Transaction txn) { if (txn != null) { try { txn.abort(); } catch (DatabaseException ignored) { // Ignore. TRACER.debugCaught(DebugLogLevel.ERROR, ignored); } } } @@ -147,18 +163,11 @@ */ public void shutdown() { dbCloseLock.writeLock().lock(); try { dbCloseLock.writeLock().lock(); try { db.close(); db = null; } finally { dbCloseLock.writeLock().unlock(); } db.close(); db = null; } catch (DatabaseException e) { @@ -167,19 +176,21 @@ mb.append(stackTraceToSingleLineString(e)); logError(mb.toMessage()); } finally { dbCloseLock.writeLock().unlock(); } } /** * Create a cursor that can be used to search or iterate on this DB. * * @param draftCN The draftCN from which the cursor must start. * @throws DatabaseException If a database error prevented the cursor * @throws ChangelogException If a database error prevented the cursor * creation. * @throws Exception if the ReplServerDBCursor creation failed. * @return The ReplServerDBCursor. */ public DraftCNDBCursor openReadCursor(int draftCN) throws DatabaseException, Exception public DraftCNDBCursor openReadCursor(int draftCN) throws ChangelogException { return new DraftCNDBCursor(draftCN); } @@ -188,14 +199,11 @@ * Create a cursor that can be used to delete some record from this * ReplicationServer database. * * @throws DatabaseException If a database error prevented the cursor * @throws ChangelogException If a database error prevented the cursor * creation. * @throws Exception if the ReplServerDBCursor creation failed. * * @return The ReplServerDBCursor. */ public DraftCNDBCursor openDeleteCursor() throws DatabaseException, Exception public DraftCNDBCursor openDeleteCursor() throws ChangelogException { return new DraftCNDBCursor(); } @@ -235,11 +243,10 @@ DatabaseEntry entry = new DatabaseEntry(); if (cursor.getFirst(key, entry, LockMode.DEFAULT) != SUCCESS) { /* database is empty */ return 0; return DATABASE_EMPTY; } return new Integer(decodeUTF8(key.getData())); return Integer.parseInt(decodeUTF8(key.getData())); } finally { @@ -248,8 +255,7 @@ } catch (DatabaseException e) { /* database is faulty */ replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); return 0; } } @@ -305,11 +311,10 @@ DatabaseEntry entry = new DatabaseEntry(); if (cursor.getLast(key, entry, LockMode.DEFAULT) != SUCCESS) { /* database is empty */ return 0; return DATABASE_EMPTY; } return new Integer(decodeUTF8(key.getData())); return Integer.parseInt(decodeUTF8(key.getData())); } finally { @@ -318,11 +323,17 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); return 0; } } private void handleUnexpectedDatabaseException(DatabaseException e) { ChangelogException ex = new ChangelogException(e); replicationServer.handleUnexpectedChangelogException(ex); } /** * {@inheritDoc} */ @@ -357,10 +368,10 @@ * * @param startingDraftCN * the draftCN from which the cursor must start. * @throws Exception * @throws ChangelogException * when the startingDraftCN does not exist. */ private DraftCNDBCursor(int startingDraftCN) throws Exception private DraftCNDBCursor(int startingDraftCN) throws ChangelogException { this.key = new ReplicationDraftCNKey(startingDraftCN); this.entry = new DatabaseEntry(); @@ -391,8 +402,9 @@ if (localCursor.getSearchKeyRange(key, entry, DEFAULT) != SUCCESS) { // We could not even move the cursor closed to it => failure throw new Exception("ChangeLog Draft Change Number " + startingDraftCN + " is not available"); throw new ChangelogException( Message.raw("ChangeLog Draft Change Number " + startingDraftCN + " is not available")); } if (localCursor.getPrev(key, entry, LockMode.DEFAULT) != SUCCESS) @@ -414,7 +426,13 @@ this.txn = null; this.cursor = localCursor; } catch (Exception e) catch (DatabaseException e) { // Unlocking is required before throwing any exception closeLockedCursor(localCursor); throw new ChangelogException(e); } catch (ChangelogException e) { // Unlocking is required before throwing any exception closeLockedCursor(localCursor); @@ -424,7 +442,7 @@ private DraftCNDBCursor() throws Exception private DraftCNDBCursor() throws ChangelogException { Transaction localTxn = null; Cursor localCursor = null; @@ -453,32 +471,20 @@ this.txn = localTxn; this.cursor = localCursor; } catch (Exception e) catch (DatabaseException e) { TRACER.debugCaught(DebugLogLevel.ERROR, e); try { closeLockedCursor(localCursor); } catch (DatabaseException ignored) { // Ignore. TRACER.debugCaught(DebugLogLevel.ERROR, ignored); } closeLockedCursor(localCursor); DraftCNDB.abort(localTxn); throw new ChangelogException(e); } catch (ChangelogException e) { TRACER.debugCaught(DebugLogLevel.ERROR, e); if (localTxn != null) { try { localTxn.abort(); } catch (DatabaseException ignored) { // Ignore. TRACER.debugCaught(DebugLogLevel.ERROR, ignored); } } closeLockedCursor(localCursor); DraftCNDB.abort(localTxn); throw e; } } @@ -508,7 +514,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } } } @@ -541,7 +547,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } } } @@ -593,7 +599,6 @@ { TRACER.debugCaught(DebugLogLevel.ERROR, e); } return null; } @@ -619,7 +624,6 @@ { TRACER.debugCaught(DebugLogLevel.ERROR, e); } return -1; } @@ -651,22 +655,22 @@ /** * Go to the next record on the cursor. * @return the next record on this cursor. * @throws DatabaseException a. * @throws ChangelogException a. */ public boolean next() throws DatabaseException public boolean next() throws ChangelogException { if (isClosed) { return false; } OperationStatus status = cursor.getNext(key, entry, LockMode.DEFAULT); if (status != OperationStatus.SUCCESS) { seqnumData = null; return false; } try { OperationStatus status = cursor.getNext(key, entry, LockMode.DEFAULT); if (status != OperationStatus.SUCCESS) { seqnumData = null; return false; } seqnumData = new DraftCNData(entry.getData()); } catch(Exception e) @@ -679,16 +683,23 @@ /** * Delete the record at the current cursor position. * * @throws DatabaseException In case of database problem. * @throws ChangelogException In case of database problem. */ public void delete() throws DatabaseException public void delete() throws ChangelogException { if (isClosed) { throw new IllegalStateException("DraftCNDB already closed"); } cursor.delete(); try { cursor.delete(); } catch (DatabaseException e) { throw new ChangelogException(e); } } /** @@ -710,10 +721,9 @@ /** * Clears this change DB from the changes it contains. * * @throws Exception Throws an exception it occurs. * @throws DatabaseException Throws a DatabaseException when it occurs. * @throws ChangelogException Throws a DatabaseException when it occurs. */ public void clear() throws Exception, DatabaseException public void clear() throws ChangelogException { // The coming users will be blocked until the clear is done dbCloseLock.writeLock().lock(); opends/src/server/org/opends/server/replication/server/DraftCNData.java
@@ -27,15 +27,16 @@ */ package org.opends.server.replication.server; import static org.opends.server.util.StaticUtils.*; import java.io.UnsupportedEncodingException; import org.opends.messages.Message; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.server.changelog.api.ChangelogException; import com.sleepycat.je.DatabaseEntry; import static org.opends.server.util.StaticUtils.*; /** * SuperClass of DatabaseEntry used for data stored in the DraftCNDB. */ @@ -66,9 +67,9 @@ /** * Creates a record to be stored in the DraftCNDB from the provided byte[]. * @param data the provided byte[]. * @throws Exception a. * @throws ChangelogException a. */ public DraftCNData(byte[] data) throws Exception public DraftCNData(byte[] data) throws ChangelogException { decodeData(data); } @@ -76,10 +77,9 @@ /** * Decode a record into fields. * @param data the provided byte array. * @throws Exception when a problem occurs. * @throws ChangelogException when a problem occurs. */ public void decodeData(byte[] data) throws Exception public void decodeData(byte[] data) throws ChangelogException { try { @@ -94,46 +94,46 @@ { // should never happens // TODO: i18n throw new ReplicationDBException(Message.raw("need UTF-8 support")); throw new ChangelogException(Message.raw("need UTF-8 support")); } } /** * Getter for the value. * * @return the value. * @throws Exception when a problem occurs. * @throws ChangelogException when a problem occurs. */ public String getValue() throws Exception public String getValue() throws ChangelogException { if (value == null) this.decodeData(this.getData()); decodeData(getData()); return this.value; } /** * Getter for the service ID. * * @return The baseDN * @throws Exception when a problem occurs. * @throws ChangelogException when a problem occurs. */ public String getBaseDN() throws Exception public String getBaseDN() throws ChangelogException { if (value == null) this.decodeData(this.getData()); decodeData(getData()); return this.baseDN; } /** * Getter for the replication change number. * * @return the replication change number. * @throws Exception when a problem occurs. * @throws ChangelogException when a problem occurs. */ public ChangeNumber getChangeNumber() throws Exception public ChangeNumber getChangeNumber() throws ChangelogException { if (value == null) this.decodeData(this.getData()); decodeData(getData()); return this.changeNumber; } opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.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.util.ArrayList; import java.util.List; import java.util.Map; @@ -48,11 +43,15 @@ import org.opends.server.replication.common.MultiDomainServerState; import org.opends.server.replication.common.ServerState; import org.opends.server.replication.server.DraftCNDB.DraftCNDBCursor; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.Attribute; import org.opends.server.types.Attributes; import org.opends.server.types.InitializationException; import com.sleepycat.je.DatabaseException; 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 for managing the replicationServer database for each @@ -60,10 +59,9 @@ * It is responsible for efficiently saving the updates that is received from * each master server into stable storage. * This class is also able to generate a ReplicationIterator that can be * used to read all changes from a given ChangeNUmber. * used to read all changes from a given ChangeNumber. * * This class publish some monitoring information below cn=monitor. * */ public class DraftCNDbHandler implements Runnable { @@ -87,11 +85,12 @@ */ private DirectoryThread thread; /** * The trim age in milliseconds. Changes record in the change DB that * are older than this age are removed. * The trim age in milliseconds. Changes record in the change DB that are * older than this age are removed. * <p> * FIXME it never gets updated even when the replication server purge delay is * updated */ // FIXME it never gets updated even when the replication server purge delay // is updated private long trimAge; private ReplicationServer replicationServer; @@ -103,11 +102,10 @@ * @param replicationServer The ReplicationServer that creates this dbHandler. * @param dbenv the Database Env to use to create the ReplicationServer DB. * server for this domain. * @throws DatabaseException If a database problem happened * @throws ChangelogException If a database problem happened */ public DraftCNDbHandler(ReplicationServer replicationServer, ReplicationDbEnv dbenv) throws DatabaseException ReplicationDbEnv dbenv) throws ChangelogException { this.replicationServer = replicationServer; this.trimAge = replicationServer.getTrimAge(); @@ -181,9 +179,10 @@ * Returns whether this database is empty. * <p> * FIXME Find a way to implement this method in a more efficient manner. * {@link Database#count()} javadoc mentions: <blockquote>Note that this * method does scan a significant portion of the database and should be * considered a fairly expensive operation.</blockquote> * {@link com.sleepycat.je.Database#count()} javadoc mentions: * <blockquote>Note that this method does scan a significant portion of the * database and should be considered a fairly expensive * operation.</blockquote> * <p> * It could be faster to: * <ul> @@ -224,13 +223,7 @@ */ public void releaseReadCursor(DraftCNDBCursor cursor) { try { cursor.close(); } catch(Exception e) { /* do nothing */ } close(cursor); } /** @@ -244,12 +237,10 @@ * managed by this dbHandler and starting at the position defined * by a given changeNumber. * * @throws DatabaseException if a database problem happened. * @throws Exception If there is no other change to push after change * with changeNumber number. * @throws ChangelogException if a database problem happened. */ public DraftCNDbIterator generateIterator(int startDraftCN) throws DatabaseException, Exception throws ChangelogException { return new DraftCNDbIterator(db, startDraftCN); } @@ -267,7 +258,7 @@ shutdown = true; synchronized (this) { this.notifyAll(); notifyAll(); } synchronized (this) @@ -276,8 +267,8 @@ { try { this.wait(); } catch (Exception e) wait(); } catch (InterruptedException e) { /* do nothing */ } } } @@ -303,7 +294,7 @@ { try { this.wait(1000); wait(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -324,16 +315,15 @@ synchronized (this) { trimDone = true; this.notifyAll(); notifyAll(); } } /** * Trim old changes from this database. * @throws DatabaseException In case of database problem. * @throws Exception In case of database problem. * @throws ChangelogException In case of database problem. */ public void trim() throws DatabaseException, Exception public void trim() throws ChangelogException { if (trimAge == 0) return; @@ -346,21 +336,17 @@ * for the provided baseDN. * @param baseDNToClear The baseDN for which we want to remove * all records from the DraftCNDb - null means all. * @throws DatabaseException When an exception occurs while removing the * @throws ChangelogException When an exception occurs while removing the * changes from the DB. * @throws Exception When an exception occurs while accessing a resource * from the DB. */ public void clear(String baseDNToClear) throws DatabaseException, Exception public void clear(String baseDNToClear) throws ChangelogException { if (isEmpty()) { return; } ChangeNumber crossDomainEligibleCN = replicationServer .getEligibleCN(); ChangeNumber crossDomainEligibleCN = replicationServer.getEligibleCN(); for (int i = 0; i < 100; i++) { @@ -406,8 +392,7 @@ // reading domain.getEligibleState(crossDomainEligibleCN); ChangeNumber fcn = startState.getChangeNumber(cn .getServerId()); ChangeNumber fcn = startState.getChangeNumber(cn.getServerId()); int currentKey = cursor.currentKey(); @@ -432,13 +417,12 @@ catch(Exception e) { // We couldn't parse the mdss from the DraftCNData Value assert(false); cursor.delete(); continue; } if ((cnVector == null) || ((cnVector.getChangeNumber(cn.getServerId()) != null) || (cnVector.getChangeNumber(cn.getServerId()) != null && !cnVector.cover(startState))) { cursor.delete(); @@ -455,7 +439,7 @@ cursor.close(); } catch (Exception e) catch (ChangelogException e) { // mark shutdown for this db so that we don't try again to // stop it from cursor.close() or methods called by cursor.close() @@ -463,6 +447,14 @@ shutdown = true; throw e; } catch (Exception e) { // mark shutdown for this db so that we don't try again to // stop it from cursor.close() or methods called by cursor.close() cursor.abort(); shutdown = true; throw new ChangelogException(e); } } } @@ -528,12 +520,10 @@ /** * Clear the changes from this DB (from both memory cache and DB storage). * @throws DatabaseException When an exception occurs while removing the * @throws ChangelogException When an exception occurs while removing the * changes from the DB. * @throws Exception When an exception occurs while accessing a resource * from the DB. */ public void clear() throws DatabaseException, Exception public void clear() throws ChangelogException { db.clear(); firstkey = db.readFirstDraftCN(); @@ -575,12 +565,11 @@ */ public String getValue(int key) { String value = null; DraftCNDBCursor draftCNDBCursor = null; try { draftCNDBCursor = db.openReadCursor(key); value = draftCNDBCursor.currentValue(); return draftCNDBCursor.currentValue(); } catch(Exception e) { @@ -597,7 +586,6 @@ { close(draftCNDBCursor); } return value; } /** @@ -607,12 +595,11 @@ */ public ChangeNumber getChangeNumber(int key) { ChangeNumber cn = null; DraftCNDBCursor draftCNDBCursor = null; try { draftCNDBCursor = db.openReadCursor(key); cn = draftCNDBCursor.currentChangeNumber(); return draftCNDBCursor.currentChangeNumber(); } catch(Exception e) { @@ -627,10 +614,8 @@ } finally { if (draftCNDBCursor != null) draftCNDBCursor.close(); close(draftCNDBCursor); } return cn; } /** @@ -640,12 +625,11 @@ */ public String getBaseDN(int key) { String sid = null; DraftCNDBCursor draftCNDBCursor = null; try { draftCNDBCursor = db.openReadCursor(key); sid = draftCNDBCursor.currentBaseDN(); return draftCNDBCursor.currentBaseDN(); } catch(Exception e) { @@ -660,9 +644,7 @@ } finally { if (draftCNDBCursor != null) draftCNDBCursor.close(); close(draftCNDBCursor); } return sid; } } opends/src/server/org/opends/server/replication/server/DraftCNDbIterator.java
@@ -27,14 +27,14 @@ */ package org.opends.server.replication.server; import static org.opends.server.loggers.debug.DebugLogger.*; import org.opends.messages.Message; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.server.DraftCNDB.DraftCNDBCursor; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.DebugLogLevel; import com.sleepycat.je.DatabaseException; import static org.opends.server.loggers.debug.DebugLogger.*; /** * This class allows to iterate through the changes received from a given @@ -53,17 +53,15 @@ * @param db The db where the iterator must be created. * @param startDraftCN The draft CN after which the iterator * must start. * @throws Exception If there is no other change to push after change * with changeNumber number. * @throws DatabaseException If a database problem happened. * @throws ChangelogException If a database problem happened. */ public DraftCNDbIterator(DraftCNDB db, int startDraftCN) throws Exception, DatabaseException throws ChangelogException { draftCNDbCursor = db.openReadCursor(startDraftCN); if (draftCNDbCursor == null) { throw new Exception("no new change"); throw new ChangelogException(Message.raw("no new change")); } } @@ -116,9 +114,9 @@ /** * Skip to the next record of the database. * @return true if has next, false elsewhere * @throws DatabaseException When database exception raised. * @throws ChangelogException When database exception raised. */ public boolean next() throws DatabaseException public boolean next() throws ChangelogException { if (draftCNDbCursor != null) { opends/src/server/org/opends/server/replication/server/ECLServerHandler.java
@@ -27,12 +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.replication.protocol.ProtocolVersion.*; import static org.opends.server.replication.protocol.StartECLSessionMsg.*; import java.io.IOException; import java.util.*; import java.util.concurrent.Semaphore; @@ -47,10 +41,15 @@ import org.opends.server.replication.common.ServerState; import org.opends.server.replication.common.ServerStatus; import org.opends.server.replication.protocol.*; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.*; import org.opends.server.util.ServerConstants; import com.sleepycat.je.DatabaseException; 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.replication.protocol.ProtocolVersion.*; import static org.opends.server.replication.protocol.StartECLSessionMsg.*; /** * This class defines a server handler, which handles all interaction with a @@ -579,11 +578,11 @@ * the start draftCN coming from the request filter. * @return the cookie corresponding to the passed in startDraftCN. * @throws Exception * if a general problem occurred * if a database problem occurred * @throws DirectoryException * if a database problem occurred */ private String findCookie(int startDraftCN) throws Exception, private String findCookie(int startDraftCN) throws ChangelogException, DirectoryException { DraftCNDbHandler draftCNDb = replicationServer.getDraftCNDbHandler(); @@ -1454,7 +1453,7 @@ + " cn=" + draftCNDbIter.getChangeNumber() + " End of draftCNDb ?" + isEndOfDraftCNReached); } catch (DatabaseException e) catch (ChangelogException e) { if (debugEnabled()) { opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
@@ -1473,10 +1473,10 @@ * Close the writer and get an LDIF reader for the LDIF content. * * @return Returns an LDIF Reader. * @throws Exception * @throws IOException * If an error occurred closing the writer. */ public LDIFReader getLDIFReader() throws Exception { public LDIFReader getLDIFReader() throws IOException { writer.close(); String ldif = stream.toString("UTF-8"); ldif = ldif.replace("\n-\n", "\n"); opends/src/server/org/opends/server/replication/server/ReplicationDB.java
@@ -27,26 +27,28 @@ */ package org.opends.server.replication.server; import static com.sleepycat.je.LockMode.*; import static com.sleepycat.je.OperationStatus.*; import static org.opends.messages.ReplicationMessages.*; import static org.opends.server.loggers.ErrorLogger.*; import static org.opends.server.util.StaticUtils.*; import java.io.Closeable; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.protocol.UpdateMsg; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.util.StaticUtils; import com.sleepycat.je.*; import static com.sleepycat.je.LockMode.*; import static com.sleepycat.je.OperationStatus.*; import static org.opends.messages.ReplicationMessages.*; import static org.opends.server.loggers.ErrorLogger.*; import static org.opends.server.util.StaticUtils.*; /** * This class implements the interface between the underlying database * and the dbHandler class. @@ -67,8 +69,7 @@ * The lock used to provide exclusive access to the thread that close the db * (shutdown or clear). */ private final ReentrantReadWriteLock dbCloseLock = new ReentrantReadWriteLock(true); private final ReadWriteLock dbCloseLock = new ReentrantReadWriteLock(true); // Change counter management // The Db itself does not allow to count records between a start and an end @@ -117,12 +118,12 @@ * @param baseDn The baseDn of the replication domain. * @param replicationServer The ReplicationServer that needs to be shutdown. * @param dbenv The Db environment to use to create the db. * @throws DatabaseException If a database problem happened. * @throws ChangelogException If a database problem happened. */ public ReplicationDB(int serverId, String baseDn, ReplicationServer replicationServer, ReplicationDbEnv dbenv) throws DatabaseException throws ChangelogException { this.serverId = serverId; this.baseDn = baseDn; @@ -138,13 +139,15 @@ intializeCounters(); } private void intializeCounters() private void intializeCounters() throws ChangelogException { this.counterCurrValue = 1; Cursor cursor = db.openCursor(null, null); Cursor cursor = null; try { cursor = db.openCursor(null, null); int distBackToCounterRecord = 0; DatabaseEntry key = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); @@ -164,9 +167,13 @@ } counterCurrValue += distBackToCounterRecord; } catch (DatabaseException e) { throw new ChangelogException(e); } finally { cursor.close(); close(cursor); } } @@ -205,7 +212,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } finally { @@ -213,7 +220,14 @@ } } private void handleUnexpectedDatabaseException(DatabaseException e) { ChangelogException ex = new ChangelogException(e); replicationServer.handleUnexpectedChangelogException(ex); } private void insertCounterRecordIfNeeded(ChangeNumber changeNumber) throws DatabaseException { if (counterCurrValue != 0 && (counterCurrValue % counterWindowSize == 0)) { @@ -276,13 +290,12 @@ * ReplicationServer DB. * * @param changeNumber The ChangeNumber from which the cursor must start. * @throws DatabaseException If a database error prevented the cursor * creation. * @throws Exception if the ReplServerDBCursor creation failed. * @throws ChangelogException * When a problem occurs or the startingChangeNumber does not exist. * @return The ReplServerDBCursor. */ public ReplServerDBCursor openReadCursor(ChangeNumber changeNumber) throws DatabaseException, Exception throws ChangelogException { return new ReplServerDBCursor(changeNumber); } @@ -291,21 +304,19 @@ * Create a cursor that can be used to delete some record from this * ReplicationServer database. * * @throws DatabaseException If a database error prevented the cursor * @throws ChangelogException If a database error prevented the cursor * creation. * @throws Exception if the ReplServerDBCursor creation failed. * * @return The ReplServerDBCursor. */ public ReplServerDBCursor openDeleteCursor() throws DatabaseException, Exception public ReplServerDBCursor openDeleteCursor() throws ChangelogException { return new ReplServerDBCursor(); } private void closeAndReleaseReadLock(Cursor cursor) throws DatabaseException private void closeAndReleaseReadLock(Cursor cursor) { try { @@ -362,7 +373,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); return null; } finally @@ -421,7 +432,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); return null; } finally @@ -482,7 +493,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } finally { @@ -492,7 +503,7 @@ } private ChangeNumber getRegularRecord(Cursor cursor, DatabaseEntry key, DatabaseEntry data) DatabaseEntry data) throws DatabaseException { final ChangeNumber cn = toChangeNumber(key.getData()); if (!isACounterRecord(cn)) @@ -548,11 +559,11 @@ * * @param startingChangeNumber * The ChangeNumber from which the cursor must start. * @throws Exception * @throws ChangelogException * When the startingChangeNumber does not exist. */ private ReplServerDBCursor(ChangeNumber startingChangeNumber) throws Exception throws ChangelogException { if (startingChangeNumber != null) { @@ -591,7 +602,8 @@ if (localCursor.getSearchKeyRange(key, data, DEFAULT) != SUCCESS) { // We could not even move the cursor closed to it => failure throw new Exception("ChangeNumber not available"); throw new ChangelogException( Message.raw("ChangeNumber not available")); } // We can move close to the startingChangeNumber. @@ -607,15 +619,21 @@ } cursor = localCursor; } catch (Exception e) catch (ChangelogException e) { // Unlocking is required before throwing any exception closeAndReleaseReadLock(localCursor); throw e; } catch (DatabaseException e) { // Unlocking is required before throwing any exception closeAndReleaseReadLock(localCursor); throw new ChangelogException(e); } } private ReplServerDBCursor() throws Exception private ReplServerDBCursor() throws ChangelogException { key = new DatabaseEntry(); data = new DatabaseEntry(); @@ -644,22 +662,32 @@ txn = localTxn; cursor = localCursor; } catch (ChangelogException e) { closeAndReleaseReadLock(localCursor); abort(localTxn); throw e; } catch (Exception e) { closeAndReleaseReadLock(localCursor); abort(localTxn); throw new ChangelogException(e); } } if (localTxn != null) private void abort(Transaction localTxn) { if (localTxn != null) { try { try { localTxn.abort(); } catch (DatabaseException ignore) { // Ignore. } localTxn.abort(); } throw e; catch (DatabaseException ignore) { // Ignore. } } } @@ -689,7 +717,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } } } @@ -722,7 +750,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } } } @@ -731,20 +759,27 @@ * Get the next ChangeNumber in the database from this Cursor. * * @return The next ChangeNumber in the database from this cursor. * @throws DatabaseException In case of underlying database problem. * @throws ChangelogException In case of underlying database problem. */ public ChangeNumber nextChangeNumber() throws DatabaseException public ChangeNumber nextChangeNumber() throws ChangelogException { if (isClosed) { return null; } if (cursor.getNext(key, data, LockMode.DEFAULT) != SUCCESS) try { return null; if (cursor.getNext(key, data, LockMode.DEFAULT) != SUCCESS) { return null; } return toChangeNumber(key.getData()); } return toChangeNumber(key.getData()); catch (DatabaseException e) { throw new ChangelogException(e); } } /** @@ -807,26 +842,32 @@ /** * Delete the record at the current cursor position. * * @throws DatabaseException In case of database problem. * @throws ChangelogException In case of database problem. */ public void delete() throws DatabaseException public void delete() throws ChangelogException { if (isClosed) { throw new IllegalStateException("ReplServerDBCursor already closed"); } cursor.delete(); try { cursor.delete(); } catch (DatabaseException e) { throw new ChangelogException(e); } } } // ReplServerDBCursor } /** * Clears this change DB from the changes it contains. * * @throws Exception Throws an exception it occurs. * @throws DatabaseException Throws a DatabaseException when it occurs. * @throws ChangelogException In case of database problem. */ public void clear() throws Exception, DatabaseException public void clear() throws ChangelogException { // The coming users will be blocked until the clear is done dbCloseLock.writeLock().lock(); @@ -915,7 +956,7 @@ } catch (DatabaseException e) { replicationServer.handleUnexpectedDatabaseException(e); handleUnexpectedDatabaseException(e); } finally { @@ -927,6 +968,7 @@ private void findFirstCounterRecordAfterStartPoint(ChangeNumber start, ChangeNumber stop, int[] counterValues, int[] distanceToCounterRecords) throws DatabaseException { Cursor cursor = db.openCursor(null, null); try @@ -981,6 +1023,7 @@ private boolean findFirstCounterRecordBeforeStopPoint(ChangeNumber start, ChangeNumber stop, int[] counterValues, int[] distanceToCounterRecords) throws DatabaseException { Cursor cursor = db.openCursor(null, null); try opends/src/server/org/opends/server/replication/server/ReplicationDBException.java
File was deleted 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); } } } opends/src/server/org/opends/server/replication/server/ReplicationIterator.java
@@ -27,11 +27,11 @@ */ package org.opends.server.replication.server; import org.opends.messages.Message; import org.opends.server.replication.common.ChangeNumber; import org.opends.server.replication.protocol.UpdateMsg; import org.opends.server.replication.server.ReplicationDB.ReplServerDBCursor; import com.sleepycat.je.DatabaseException; import org.opends.server.replication.server.changelog.api.ChangelogException; /** * This class allows to iterate through the changes received from a given @@ -53,12 +53,10 @@ * @param db The db where the iterator must be created. * @param changeNumber The ChangeNumber after which the iterator must start. * @param dbHandler The associated DbHandler. * @throws Exception If there is no other change to push after change * with changeNumber number. * @throws DatabaseException if a database problem happened. * @throws ChangelogException if a database problem happened. */ public ReplicationIterator(ReplicationDB db, ChangeNumber changeNumber, DbHandler dbHandler) throws Exception, DatabaseException DbHandler dbHandler) throws ChangelogException { this.db = db; this.dbh = dbHandler; @@ -83,7 +81,7 @@ cursor = db.openReadCursor(changeNumber); if (cursor == null) { throw new Exception("no new change"); throw new ChangelogException(Message.raw("no new change")); } } } opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -27,12 +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.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import java.io.File; import java.io.IOException; import java.io.StringReader; @@ -58,13 +52,18 @@ import org.opends.server.replication.common.*; import org.opends.server.replication.plugin.MultimasterReplication; import org.opends.server.replication.protocol.*; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.*; import org.opends.server.util.LDIFReader; import org.opends.server.util.ServerConstants; import org.opends.server.util.TimeThread; import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement; import com.sleepycat.je.DatabaseException; 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.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; /** * ReplicationServer Listener. This singleton is the main object of the @@ -559,15 +558,11 @@ TRACER.debugInfo("RS " +getMonitorInstanceName()+ " successfully initialized"); } catch (DatabaseException e) } catch (ChangelogException e) { Message message = ERR_COULD_NOT_INITIALIZE_DB.get( getFileForPath(dbDirname).getAbsolutePath()); logError(message); } catch (ReplicationDBException e) { Message message = ERR_COULD_NOT_READ_DB.get(dbDirname, e.getLocalizedMessage()); Message message = ERR_COULD_NOT_READ_DB.get( getFileForPath(dbDirname).getAbsolutePath(), e.getLocalizedMessage()); logError(message); } catch (UnknownHostException e) { @@ -870,10 +865,10 @@ * @param baseDn The DN for which the dbHandler must be created. * @return The new DB handler for this ReplicationServer and the serverId and * DN given in parameter. * @throws DatabaseException in case of underlying database problem. * @throws ChangelogException in case of underlying database problem. */ public DbHandler newDbHandler(int id, String baseDn) throws DatabaseException throws ChangelogException { return new DbHandler(id, baseDn, this, dbEnv, queueSize); } @@ -967,6 +962,7 @@ ServerSocket tmpSocket = new ServerSocket(); tmpSocket.bind(new InetSocketAddress(port)); tmpSocket.close(); return true; } catch (Exception e) { @@ -974,8 +970,6 @@ unacceptableReasons.add(message); return false; } return true; } /** @@ -1262,7 +1256,6 @@ mb.append(e.getLocalizedMessage()); Message msg = ERR_CHECK_CREATE_REPL_BACKEND_FAILED.get(mb.toString()); throw new ConfigException(msg, e); } } @@ -1941,7 +1934,7 @@ * @param e * The unexpected database exception. */ void handleUnexpectedDatabaseException(DatabaseException e) void handleUnexpectedChangelogException(ChangelogException e) { MessageBuilder mb = new MessageBuilder(); mb.append(ERR_CHANGELOG_SHUTDOWN_DATABASE_ERROR.get()); opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.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.IOException; import java.io.UnsupportedEncodingException; import java.util.*; @@ -51,10 +46,14 @@ import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.replication.common.*; import org.opends.server.replication.protocol.*; import org.opends.server.replication.server.changelog.api.ChangelogException; import org.opends.server.types.*; import org.opends.server.util.TimeThread; import com.sleepycat.je.DatabaseException; 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 define an in-memory cache that will be used to store @@ -319,7 +318,7 @@ { dbHandler = replicationServer.newDbHandler(id, baseDn); generationIdSavedStatus = true; } catch (DatabaseException e) } catch (ChangelogException e) { /* * Because of database problem we can't save any more changes @@ -1452,10 +1451,10 @@ * associated the DbHandler. * @param dbHandler the dbHandler associated to the serverId. * * @throws DatabaseException If a database error happened. * @throws ChangelogException If a database error happened. */ public void setDbHandler(int serverId, DbHandler dbHandler) throws DatabaseException throws ChangelogException { synchronized (sourceDbHandlers) { @@ -1899,7 +1898,7 @@ } } } try { Thread.sleep(100); } catch(Exception e) {} sleep(100); } } } @@ -1935,11 +1934,16 @@ } } } try { Thread.sleep(100); } catch(Exception e) {} sleep(100); } } } private void sleep(int millis) { try { Thread.sleep(millis); } catch (InterruptedException e) {} } /** * Creates a TopologyMsg filled with information to be sent to a remote RS. * We send remote RS the info of every DS that are directly connected to us @@ -2172,7 +2176,6 @@ Message message = NOTE_RESET_GENERATION_ID.get(baseDn, newGenId); logError(message); } catch(Exception e) { @@ -3114,7 +3117,7 @@ ChangeNumber newCN = ri.getChange().getChangeNumber(); result.update(newCN); } } catch (Exception e) { } catch (ChangelogException e) { // there's no change older than eligibleCN (case of s3/cn31) result.update(new ChangeNumber(0, 0, serverId)); } finally { opends/src/server/org/opends/server/replication/server/changelog/api/ChangelogException.java
New file @@ -0,0 +1,77 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2013 ForgeRock AS */ package org.opends.server.replication.server.changelog.api; import org.opends.messages.Message; import org.opends.server.types.OpenDsException; /** * This class define an Exception that must be used when some error condition * was detected in the changelog database that cannot be recovered * automatically. */ public class ChangelogException extends OpenDsException { /** Generated serialization ID. */ private static final long serialVersionUID = -8444837053769661394L; /** * Creates a new changelog exception with the provided information. * * @param message * The message that explains the problem that occurred. */ public ChangelogException(Message message) { super(message); } /** * Creates a new changelog exception with the provided information. * * @param cause * The underlying cause that triggered this exception. */ public ChangelogException(Throwable cause) { super(cause); } /** * Creates a new identified exception with the provided information. * * @param message * The message that explains the problem that occurred. * @param cause * The underlying cause that triggered this exception. */ protected ChangelogException(Message message, Throwable cause) { super(message, cause); } } opends/src/server/org/opends/server/replication/server/changelog/api/package-info.java
New file @@ -0,0 +1,44 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2013 ForgeRock AS */ /** * This package contains the API for the changelog database. The changelog * contains: * <ul> * <li>a changelog of all the changes that happened on each server in the * replication domain / suffix,</li> * <li>a draft changelog,</li> * <li>a state database containing specific information about each serverId in * the suffix, and in particular the generationId for each server.</li> * </ul> * * The changelog must be purged at regular intervals to ensure it does not * consume too much space on disk. */ @org.opends.server.types.PublicAPI( stability = org.opends.server.types.StabilityLevel.PRIVATE) package org.opends.server.replication.server.changelog.api;