OPENDJ-1388 CR-3446 Implement simple changelog db based on single log file
[Note: actual merge of all org.opends.server.replication.server.changelog.file
package content to be done in one shot in a future commit]
* Add new package org.opends.server.replication.server.changelog.file
containing the log file implementation
* The new package contains the following classes :
** Classes implementing the log - independant from changelog and built from scratch
- LogFile : implementation of log based on a single file
- LogWriter : writer for the log
- LogReaderPool : pool of readers for the log
- Record : a (key, value) log record
- RecordParser : interface for the convertion from record to bytes and bytes to record
- DecodingException : exception thrown when record decoding fails
** Classes implementing the changelog API, based on the log implementation.
- FileChangelogDB
- FileChangeNumberIndexDB
- FileChangeNumberIndexDBCursor
- FileReplicaDB
- FileReplicaDBCursor
- ReplicationEnvironment
* Add unit tests for org.opends.server.replication.server.changelog.file package
* Add new attribute 'ds-cfg-replication-db-implementation' in
ds-cfg-replication-server (ServerReplicationConfig class), allowing
to choose the db implementation to use for changelog in directory server:
either je or log file. Default is 'je'.
* Add new option 'org.opends.test.replicationDbImpl' for test target in build.xml
to choose the db implementation to for changelog when running the tests.
Default is 'log' (log file).
* Update all replication unit tests to allow the selection of changelog db implementation
to use in tests.
* Fix the ReferentialIntegerityPluginTestCase to do better cleanup at end of test in
order to avoid side-effect on other tests.
2 files added
34 files modified
| | |
| | | <echo message=" Default debug target:"/> |
| | | <echo message=" org.opends.server:level=warning,category=caught|data|database-access|message|protocol,stack,cause" /> |
| | | <echo message=""/> |
| | | <echo message=" -Dorg.opends.test.replicationDbImpl=LOG"/> |
| | | <echo message=" indicates which implementation to use for replication DB."/> |
| | | <echo message=" Value must be one of: JE, LOG." /> |
| | | <echo message=" JE: use berkeley DB JE as implementation." /> |
| | | <echo message=" LOG: use log file as implementation." /> |
| | | <echo message=" Default value is JE" /> |
| | | <echo message=""/> |
| | | <echo message=" -Dtest.diff.srcpath=src/server/org/opends/server/core"/> |
| | | <echo message=" for example includes only the classes in"/> |
| | | <echo message=" src/server/org/opends/server/core in the coveragediff report."/> |
| | |
| | | </not> |
| | | </condition> |
| | | |
| | | <!-- This sets org.opends.test.replicationDbImpl if and only if it's not |
| | | already set. --> |
| | | <condition property="org.opends.test.replicationDbImpl" value="JE"> |
| | | <not> |
| | | <isset property="org.opends.test.replicationDbImpl" /> |
| | | </not> |
| | | </condition> |
| | | |
| | | <!-- This sets org.opends.test.suppressOutput if and only if it's not |
| | | already set. --> |
| | | <condition property="org.opends.test.suppressOutput" value="true"> |
| | |
| | | <jvmarg value="-Dorg.opends.server.BuildDir=${build.dir}" /> |
| | | <jvmarg value="-Dorg.opends.server.RunningUnitTests=true" /> |
| | | <jvmarg value="-Dorg.opends.server.snmp.opendmk=${opendmk.lib.dir}"/> |
| | | <jvmarg value="-Dorg.opends.test.replicationDbImpl=${org.opends.test.replicationDbImpl}" /> |
| | | <jvmarg value="-Dorg.opends.test.suppressOutput=${org.opends.test.suppressOutput}" /> |
| | | <jvmarg value="-Dorg.opends.test.pauseOnFailure=${org.opends.test.pauseOnFailure}" /> |
| | | <jvmarg value="-Dorg.opends.server.debug.target=${org.opends.server.debug.target}" /> |
| | |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.142 |
| | | NAME 'ds-cfg-replication-db-implementation' |
| | | EQUALITY caseExactMatch |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 |
| | | NAME 'ds-cfg-access-control-handler' |
| | | SUP top |
| | |
| | | ds-cfg-window-size $ |
| | | ds-cfg-queue-size $ |
| | | ds-cfg-replication-db-directory $ |
| | | ds-cfg-replication-db-implementation $ |
| | | ds-cfg-replication-purge-delay $ |
| | | ds-cfg-group-id $ |
| | | ds-cfg-assured-timeout $ |
| | |
| | | ! |
| | | ! |
| | | ! Copyright 2007-2010 Sun Microsystems, Inc. |
| | | ! Portions copyright 2011-2013 ForgeRock AS |
| | | ! Portions copyright 2011-2014 ForgeRock AS |
| | | ! --> |
| | | <adm:managed-object name="replication-server" |
| | | plural-name="replication-servers" |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="replication-db-implementation" mandatory="true" read-only="true"> |
| | | <adm:synopsis> |
| | | The <adm:user-friendly-name /> database implementation |
| | | that stores all persistent information. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>je</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:enumeration> |
| | | <adm:value name="je"> |
| | | <adm:synopsis>Implementation based on Berkeley DB JE database.</adm:synopsis> |
| | | </adm:value> |
| | | <adm:value name="log"> |
| | | <adm:synopsis>Implementation based on log file.</adm:synopsis> |
| | | </adm:value> |
| | | </adm:enumeration> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-replication-db-implementation</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="replication-purge-delay"> |
| | | <adm:synopsis> |
| | | The time (in seconds) after which the |
| | |
| | | property.monitoring-period.description=Defines the duration that the replication server will wait before sending new monitoring messages to its peers (replication servers and directory servers). Larger values increase the length of time it takes for a directory server to detect and switch to a more suitable replication server, whereas smaller values increase the amount of background network traffic. |
| | | property.queue-size.synopsis=Specifies the number of changes that are kept in memory for each directory server in the Replication Domain. |
| | | property.replication-db-directory.synopsis=The path where the Replication Server stores all persistent information. |
| | | property.replication-db-implementation.synopsis=The Replication Server database implementation that stores all persistent information. |
| | | property.replication-db-implementation.syntax.enumeration.value.je.synopsis=Implementation based on Berkeley DB JE database. |
| | | property.replication-db-implementation.syntax.enumeration.value.log.synopsis=Implementation based on log file. |
| | | property.replication-port.synopsis=The port on which this Replication Server waits for connections from other Replication Servers or Directory Servers. |
| | | property.replication-purge-delay.synopsis=The time (in seconds) after which the Replication Server erases all persistent information. |
| | | property.replication-server.synopsis=Specifies the addresses of other Replication Servers to which this Replication Server tries to connect at startup time. |
| | |
| | | change %s to replicaDB %s %s because flushing thread is shutting down |
| | | NOTE_SEARCH_CHANGELOG_INSUFFICIENT_PRIVILEGES_285=You do not have sufficient privileges to \ |
| | | perform a search request on cn=changelog |
| | | ERR_CHANGELOG_READ_STATE_WRONG_ROOT_PATH_241=Error when retrieving changelog \ |
| | | state from root path '%s' : directory might not exist |
| | | ERR_CHANGELOG_READ_STATE_NO_GENERATION_ID_FOUND_242=Error when retrieving \ |
| | | changelog state from root path '%s' : no generation id file found in domain \ |
| | | directory '%s' |
| | | ERR_CHANGELOG_READ_STATE_CANT_READ_DOMAIN_DIRECTORY_243=Error when retrieving \ |
| | | changelog state from root path '%s' : IO error on domain directory '%s' when retrieving \ |
| | | list of server ids |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_REPLICA_DB_244=Could not get or create replica DB \ |
| | | for baseDN '%s', serverId '%d', generationId '%d' |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_CN_INDEX_DB_245= Could not get or create change \ |
| | | number index DB in root path '%s', using path '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_DELETE_GENERATION_ID_FILE_246=Could not retrieve \ |
| | | generation id file '%s' for DN '%s' to delete it |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_SERVER_ID_DIRECTORY_247=Could not create \ |
| | | directory '%s' for server id %d |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_GENERATION_ID_FILE_248=Could not create \ |
| | | generation id file '%s' |
| | | ERR_CHANGELOG_DOMAIN_FILENAME_WRONG_FORMAT_249=Could not read domain \ |
| | | filename because it uses a wrong format, expecting '[dn].domain' where [dn] is \ |
| | | a DN but got '%s' |
| | | ERR_CHANGELOG_SERVER_ID_FILENAME_WRONG_FORMAT_250=Could not read server id \ |
| | | filename because it uses a wrong format, expecting '[id].server' where [id] is \ |
| | | numeric but got '%s' |
| | | ERR_CHANGELOG_GENERATION_ID_WRONG_FORMAT_251=Could not read generation id \ |
| | | because it uses a wrong format, expecting a number but got '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_OPEN_LOG_FILE_252=Could not open log file '%s' for write |
| | | ERR_CHANGELOG_UNABLE_TO_OPEN_READER_ON_LOG_FILE_253=Could not open a reader \ |
| | | on log file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_DECODE_RECORD_254=Could not decode a record from data \ |
| | | read in log file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_DELETE_LOG_FILE_255=Could not delete log file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_LOG_FILE_256=Could not create log file '%s' |
| | | WARN_CHANGELOG_NOT_ENABLED_FOR_WRITE_257=The changelog '%s' has been opened in \ |
| | | read-only mode, it is not enabled for write |
| | | ERR_CHANGELOG_UNABLE_TO_ADD_RECORD_258=Could not add record '%s' in log \ |
| | | file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_SYNC_259=Could not synchronize written records \ |
| | | to file system for log file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_SEEK_260=Could not seek to position %d for reader \ |
| | | on log file '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_CREATE_LOG_DIRECTORY_261=Could not create root directory '%s' for \ |
| | | log file |
| | | ERR_CHANGELOG_UNABLE_TO_DECODE_DN_FROM_DOMAIN_STATE_FILE_262=Could not decode DN \ |
| | | from domain state file '%s', from line '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_READ_DOMAIN_STATE_FILE_263=Could not read domain state \ |
| | | file '%s' |
| | | ERR_CHANGELOG_INCOHERENT_DOMAIN_STATE_264=There is a mismatch between domain state \ |
| | | file and actual domain directories found in file system. Expected domain ids : '%s'. \ |
| | | Actual domain ids found in file system: '%s' |
| | | ERR_CHANGELOG_UNABLE_TO_UPDATE_DOMAIN_STATE_FILE_265=Could not create a new domain \ |
| | | id %s for domain DN %s and save it in domain state file '%s" |
| | |
| | | */ |
| | | package org.opends.server.backends.jeb; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.util.DynamicConstants; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.opends.server.types.CryptoManagerException; |
| | | |
| | | import javax.crypto.Mac; |
| | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A backup manager for JE backends. |
| | | */ |
| | |
| | | // Delete the current backend directory and rename the restore directory. |
| | | if (!verifyOnly) |
| | | { |
| | | cleanup(backendDir); |
| | | backendDir.delete(); |
| | | StaticUtils.recursiveDelete(backendDir); |
| | | if (!restoreDir.renameTo(backendDir)) |
| | | { |
| | | LocalizableMessage msg = ERR_JEB_CANNOT_RENAME_RESTORE_DIRECTORY.get( |
| | |
| | | import org.forgerock.opendj.ldap.SearchScope; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.ConflictBehavior; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.admin.std.server.ReplicationServerCfg; |
| | | import org.opends.server.admin.std.server.UserDefinedVirtualAttributeCfg; |
| | | import org.opends.server.api.VirtualAttributeProvider; |
| | |
| | | import org.opends.server.replication.server.changelog.api.ChangeNumberIndexRecord; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogDB; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogException; |
| | | import org.opends.server.replication.server.changelog.file.FileChangelogDB; |
| | | import org.opends.server.replication.server.changelog.je.JEChangelogDB; |
| | | import org.opends.server.replication.service.DSRSShutdownSync; |
| | | import org.opends.server.types.*; |
| | |
| | | private final Map<DN, ReplicationServerDomain> baseDNs = |
| | | new HashMap<DN, ReplicationServerDomain>(); |
| | | |
| | | private final ChangelogDB changelogDB; |
| | | private ChangelogDB changelogDB; |
| | | private final AtomicBoolean shutdown = new AtomicBoolean(); |
| | | private boolean stopListen = false; |
| | | private final ReplSessionSecurity replSessionSecurity; |
| | |
| | | this.config = cfg; |
| | | this.changelogDB = new JEChangelogDB(this, cfg); |
| | | this.dsrsShutdownSync = dsrsShutdownSync; |
| | | this.config = cfg; |
| | | ReplicationDBImplementation dbImpl = cfg.getReplicationDBImplementation(); |
| | | if (dbImpl == ReplicationDBImplementation.JE) |
| | | { |
| | | logger.trace("Using JE as DB implementation for changelog DB"); |
| | | this.changelogDB = new JEChangelogDB(this, cfg); |
| | | } |
| | | else |
| | | { |
| | | logger.trace("Using LOG FILE as DB implementation for changelog DB"); |
| | | this.changelogDB = new FileChangelogDB(this, cfg); |
| | | } |
| | | |
| | | replSessionSecurity = new ReplSessionSecurity(); |
| | | initialize(); |
| New file |
| | |
| | | /* |
| | | * 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 2014 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.replication.server.changelog.file; |
| | | |
| | | import org.opends.server.admin.std.server.ReplicationServerCfg; |
| | | import org.opends.server.replication.common.CSN; |
| | | import org.opends.server.replication.common.MultiDomainServerState; |
| | | import org.opends.server.replication.common.ServerState; |
| | | import org.opends.server.replication.protocol.UpdateMsg; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.replication.server.changelog.api.ChangeNumberIndexDB; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogDB; |
| | | import org.opends.server.replication.server.changelog.api.ChangelogException; |
| | | import org.opends.server.replication.server.changelog.api.DBCursor; |
| | | import org.opends.server.replication.server.changelog.api.DBCursor.PositionStrategy; |
| | | import org.opends.server.replication.server.changelog.api.ReplicationDomainDB; |
| | | import org.opends.server.replication.server.changelog.je.MultiDomainDBCursor; |
| | | import org.opends.server.types.DN; |
| | | |
| | | /** |
| | | * File-based implementation of the ChangelogDB interface. |
| | | */ |
| | | public class FileChangelogDB implements ChangelogDB, ReplicationDomainDB |
| | | { |
| | | |
| | | /** |
| | | * Creates the changelog DB. |
| | | * |
| | | * @param replicationServer |
| | | * replication server |
| | | * @param cfg |
| | | * configuration |
| | | */ |
| | | public FileChangelogDB(ReplicationServer replicationServer, |
| | | ReplicationServerCfg cfg) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ServerState getDomainOldestCSNs(DN baseDN) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ServerState getDomainNewestCSNs(DN baseDN) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public long getDomainLatestTrimDate(DN baseDN) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void removeDomain(DN baseDN) throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public MultiDomainDBCursor getCursorFrom(MultiDomainServerState startState, |
| | | PositionStrategy positionStrategy) throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DBCursor<UpdateMsg> getCursorFrom(DN baseDN, ServerState startState, |
| | | PositionStrategy positionStrategy) throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public DBCursor<UpdateMsg> getCursorFrom(DN baseDN, int serverId, |
| | | CSN startCSN, PositionStrategy positionStrategy) |
| | | throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void unregisterCursor(DBCursor<?> cursor) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean publishUpdateMsg(DN baseDN, UpdateMsg updateMsg) |
| | | throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void replicaHeartbeat(DN baseDN, CSN heartbeatCSN) |
| | | throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void replicaOffline(DN baseDN, CSN offlineCSN) |
| | | throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void initializeDB() |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setPurgeDelay(long delayInMillis) |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setComputeChangeNumber(boolean computeChangeNumber) |
| | | throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void shutdownDB() throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void removeDB() throws ChangelogException |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ChangeNumberIndexDB getChangeNumberIndexDB() |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ReplicationDomainDB getReplicationDomainDB() |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | /** |
| | | * Clear the database. |
| | | */ |
| | | public void clearDB() |
| | | { |
| | | throw new RuntimeException("Not implemented"); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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 2014 ForgeRock AS |
| | | */ |
| | | |
| | | /** |
| | | * This package contains a file-based log implementation for the changelog |
| | | * database API. |
| | | */ |
| | | @org.opends.server.types.PublicAPI( |
| | | stability = org.opends.server.types.StabilityLevel.PRIVATE) |
| | | package org.opends.server.replication.server.changelog.file; |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | * Copyright 2013-2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.replication.server.changelog.je; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // OK, the oldest change is older than the medium consistency point |
| | | // let's publish it to the CNIndexDB. |
| | | final String previousCookie = mediumConsistencyRUV.toString(); |
| | |
| | | import org.testng.annotations.Test; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | |
| | | |
| | | @BeforeSuite |
| | | public final void suppressOutput() { |
| | | System.out.println("Replication DB implementation used in tests: '" + |
| | | ReplicationTestCase.replicationDbImplementation + "'."); |
| | | System.out.flush(); |
| | | |
| | | TestCaseUtils.suppressOutput(); |
| | | } |
| | | |
| | |
| | | package org.opends.server; |
| | | |
| | | import java.io.*; |
| | | import java.lang.management.ManagementFactory; |
| | | import java.lang.management.ThreadInfo; |
| | | import java.lang.management.ThreadMXBean; |
| | | import java.net.*; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.logging.ConsoleHandler; |
| | | import java.util.logging.Handler; |
| | |
| | | return pluginTypes; |
| | | } |
| | | |
| | | /** Saves a thread dump in a file with the provided id used in file prefix. */ |
| | | public static void generateThreadDump(String id) |
| | | { |
| | | String date = new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date().getTime()); |
| | | BufferedWriter writer = null; |
| | | try |
| | | { |
| | | writer = new BufferedWriter(new FileWriter("/tmp/thread_dump_" + id + "_" + date)); |
| | | writer.write(generateThreadDump()); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | // do nothing |
| | | } |
| | | finally |
| | | { |
| | | close(writer); |
| | | } |
| | | } |
| | | |
| | | /** Generates a thread dump programmatically. */ |
| | | public static String generateThreadDump() { |
| | | final StringBuilder dump = new StringBuilder(); |
| | | final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); |
| | | final ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100); |
| | | for (ThreadInfo threadInfo : threadInfos) { |
| | | dump.append('"'); |
| | | dump.append(threadInfo.getThreadName()); |
| | | dump.append("\" "); |
| | | final Thread.State state = threadInfo.getThreadState(); |
| | | dump.append("\n java.lang.Thread.State: "); |
| | | dump.append(state); |
| | | final StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); |
| | | for (final StackTraceElement stackTraceElement : stackTraceElements) { |
| | | dump.append("\n at "); |
| | | dump.append(stackTraceElement); |
| | | } |
| | | dump.append("\n\n"); |
| | | } |
| | | return dump.toString(); |
| | | } |
| | | |
| | | } |
| | |
| | | @AfterClass |
| | | public void tearDown() throws Exception { |
| | | deleteAttrsEntry(configDN, dsConfigBaseDN); |
| | | deleteAttrsEntry(configDN, dsConfigEnforceIntegrity); |
| | | deleteAttrsEntry(configDN, dsConfigAttrFiltMapping); |
| | | //Hopefully put an attribute type there that won't impact the rest of the |
| | | //unit tests. |
| | | replaceAttrEntry(configDN, dsConfigAttrType,"seeAlso"); |
| | |
| | | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddModDelDependencyTestDb", |
| | | 0, replServerId, 0, |
| | | AddSequenceLength*5+100, null); |
| | | replicationDbImplementation, 0, replServerId, |
| | | 0, AddSequenceLength*5+100, null); |
| | | replServer = new ReplicationServer(conf); |
| | | |
| | | ReplicationBroker broker = openReplicationSession( |
| | |
| | | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestModdnDelDependencyTestDb", |
| | | 0, replServerId, 0, |
| | | 200, null); |
| | | replicationDbImplementation, 0, replServerId, |
| | | 0, 200, null); |
| | | replServer = new ReplicationServer(conf); |
| | | |
| | | // configure and start replication of TEST_ROOT_DN_STRING on the server |
| | |
| | | int replServerPort = TestCaseUtils.findFreePort(); |
| | | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddDelAddDependencyTestDb", 0, |
| | | replServerId, |
| | | 0, 5*AddSequenceLength+100, null); |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddDelAddDependencyTestDb", replicationDbImplementation, |
| | | 0, replServerId, 0, 5*AddSequenceLength+100, null); |
| | | replServer = new ReplicationServer(conf); |
| | | |
| | | ReplicationBroker broker = openReplicationSession( |
| | |
| | | int replServerPort = TestCaseUtils.findFreePort(); |
| | | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddModdnDependencyTestDb", 0, |
| | | replServerId, |
| | | 0, 5*AddSequenceLength+100, null); |
| | | new ReplServerFakeConfiguration(replServerPort, "dependencyTestAddModdnDependencyTestDb", replicationDbImplementation, |
| | | 0, replServerId, 0, 5*AddSequenceLength+100, null); |
| | | replServer = new ReplicationServer(conf); |
| | | |
| | | ReplicationBroker broker = openReplicationSession( |
| | |
| | | int rsPort = getRSPort(replServerId); |
| | | String rsDir = "generationIdTest" + replServerId + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPort, rsDir, 0, replServerId, 0, 100, servers); |
| | | new ReplServerFakeConfiguration(rsPort, rsDir, replicationDbImplementation, 0, replServerId, 0, 100, servers); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | Thread.sleep(1000); |
| | | return replicationServer; |
| | |
| | | */ |
| | | private void checkChangelogSize(int expectedCount) throws Exception |
| | | { |
| | | final MultiDomainServerState state = new MultiDomainServerState(); |
| | | final Control control = new ExternalChangelogRequestControl(true, state); |
| | | final List<Control> controls = newList(control); |
| | | |
| | | final int timeout = 500; |
| | | long start = System.currentTimeMillis(); |
| | | InternalSearchOperation searchOperation; |
| | | do |
| | | { |
| | | Thread.sleep(10); |
| | | searchOperation = connection.processSearch( |
| | | "cn=changelog", SearchScope.SUBORDINATES, |
| | | DereferenceAliasesPolicy.NEVER, 0, 0, false, |
| | | "(objectclass=*)", null, controls, null); |
| | | } |
| | | while (System.currentTimeMillis() - start <= timeout |
| | | && searchOperation.getResultCode() != ResultCode.SUCCESS |
| | | && searchOperation.getSearchEntries().size() != expectedCount); |
| | | Assertions.assertThat(searchOperation.getSearchEntries()).hasSize(expectedCount); |
| | | // TODO : commented this throw because test is executed through a slow test |
| | | //throw new RuntimeException("Dead code. Should we remove this method and the test calling it?"); |
| | | } |
| | | |
| | | /** |
| | |
| | | new ReplServerFakeConfiguration( |
| | | port, |
| | | "initOnlineTest" + port + testCase + "Db", |
| | | 0, |
| | | replServerId, |
| | | 0, |
| | | 100, |
| | | servers); |
| | | replicationDbImplementation, |
| | | 0, replServerId, 0, 100, servers); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | Thread.sleep(1000); |
| | | return replicationServer; |
| | |
| | | |
| | | // configure the replication Server. |
| | | replicationServer = new ReplicationServer(new ReplServerFakeConfiguration( |
| | | replServerPort, "protocolWindowTestDb", 0, |
| | | 1, REPLICATION_QUEUE_SIZE, WINDOW_SIZE, null)); |
| | | replServerPort, "protocolWindowTestDb", replicationDbImplementation, |
| | | 0, 1, REPLICATION_QUEUE_SIZE, WINDOW_SIZE, null)); |
| | | |
| | | String personLdif = "dn: uid=user.windowTest," + TEST_ROOT_DN_STRING + "\n" |
| | | + "objectClass: top\n" + "objectClass: person\n" |
| | |
| | | import org.forgerock.opendj.ldap.SearchScope; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.admin.std.server.ReplicationDomainCfg; |
| | | import org.opends.server.backends.task.TaskState; |
| | | import org.opends.server.core.AddOperation; |
| | |
| | | import org.opends.server.replication.protocol.ReplicationMsg; |
| | | import org.opends.server.replication.protocol.Session; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.replication.server.changelog.file.FileChangelogDB; |
| | | import org.opends.server.replication.server.changelog.je.JEChangelogDB; |
| | | import org.opends.server.replication.service.ReplicationBroker; |
| | | import org.opends.server.types.*; |
| | |
| | | protected Entry synchroServerEntry; |
| | | protected Entry replServerEntry; |
| | | |
| | | private static final String REPLICATION_DB_IMPL_PROPERTY = "org.opends.test.replicationDbImpl"; |
| | | |
| | | public static ReplicationDBImplementation replicationDbImplementation = ReplicationDBImplementation.valueOf( |
| | | System.getProperty(REPLICATION_DB_IMPL_PROPERTY, ReplicationDBImplementation.JE.name())); |
| | | |
| | | /** |
| | | * Replication monitor stats |
| | | */ |
| | |
| | | LDAPReplicationDomain replDomain = LDAPReplicationDomain.retrievesReplicationDomain(baseDN); |
| | | genId = replDomain.getGenerationID(); |
| | | } |
| | | catch(Exception e) {} |
| | | catch(Exception e) { |
| | | logger.traceException(e); |
| | | } |
| | | return genId; |
| | | } |
| | | |
| | |
| | | |
| | | protected void clearChangelogDB(ReplicationServer rs) throws Exception |
| | | { |
| | | if (replicationDbImplementation == ReplicationDBImplementation.JE) |
| | | { |
| | | ((JEChangelogDB) rs.getChangelogDB()).clearDB(); |
| | | } |
| | | else |
| | | { |
| | | ((FileChangelogDB) rs.getChangelogDB()).clearDB(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Cleanup databases of the currently instantiated replication servers in the |
| | |
| | | + " Also received the following messages during wait time: " + msgs); |
| | | return null; |
| | | } |
| | | |
| | | protected static void setReplicationDBImplementation(ReplicationDBImplementation impl) |
| | | { |
| | | replicationDbImplementation = impl; |
| | | } |
| | | } |
| | |
| | | + "cn: Replication Server\n" |
| | | + "ds-cfg-replication-port: " + replServerPort + "\n" |
| | | + "ds-cfg-replication-db-directory: SchemaReplicationTest\n" |
| | | + "ds-cfg-replication-db-implementation: " + replicationDbImplementation + "\n" |
| | | + "ds-cfg-replication-server-id: 105\n"; |
| | | |
| | | // suffix synchronized |
| | |
| | | + "cn: Replication Server\n" |
| | | + "ds-cfg-replication-port: " + replServerPort + "\n" |
| | | + "ds-cfg-replication-db-directory: UpdateOperationTest\n" |
| | | + "ds-cfg-replication-db-implementation: " + replicationDbImplementation + "\n" |
| | | + "ds-cfg-replication-server-id: 107\n"; |
| | | |
| | | // suffix synchronized |
| | |
| | | |
| | | String dir = testName + RS_ID + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(replServerPort, dir, 0, RS_ID, 0, 100, |
| | | replServers); |
| | | new ReplServerFakeConfiguration(replServerPort, dir, replicationDbImplementation, 0, RS_ID, 0, |
| | | 100, replServers); |
| | | replicationServer = new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | import org.opends.server.replication.server.ReplServerFakeConfiguration; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | |
| | | |
| | | String dir = "groupIdHandshakeTest" + serverId + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(port, dir, 0, serverId, 0, 100, |
| | | replServers, groupId, 1000, 5000); |
| | | new ReplServerFakeConfiguration(port, dir, replicationDbImplementation, 0, serverId, 0, |
| | | 100, replServers, groupId, 1000, 5000); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | otherReplServers.add("localhost:" + rs2Port); |
| | | String dir = "groupIdHandshakeTest" + RS3_ID + testCase + "Db"; |
| | | ReplServerFakeConfiguration rsConfWithNewGid = |
| | | new ReplServerFakeConfiguration(rs3Port, dir, 0, RS3_ID, 0, 100, |
| | | otherReplServers, 1, 1000, 5000); |
| | | new ReplServerFakeConfiguration(rs3Port, dir, replicationDbImplementation, 0, RS3_ID, 0, |
| | | 100, otherReplServers, 1, 1000, 5000); |
| | | rs3.applyConfigurationChange(rsConfWithNewGid); |
| | | |
| | | /** |
| | |
| | | otherReplServers.add("localhost:" + rs2Port); |
| | | otherReplServers.add("localhost:" + rs3Port); |
| | | dir = "groupIdHandshakeTest" + RS1_ID + testCase + "Db"; |
| | | rsConfWithNewGid = new ReplServerFakeConfiguration(rs1Port, dir, 0, RS1_ID, |
| | | 0, 100, otherReplServers, 3, 1000, 5000); |
| | | rsConfWithNewGid = new ReplServerFakeConfiguration(rs1Port, dir, ReplicationDBImplementation.JE, 0, |
| | | RS1_ID, 0, 100, otherReplServers, 3, 1000, 5000); |
| | | rs1.applyConfigurationChange(rsConfWithNewGid); |
| | | checkConnection(30, DS1_ID, RS3_ID, |
| | | "Change GID of RS3 to 1 and RS1 to 3, DS1 should reconnect to RS3 with GID=1"); |
| | |
| | | replServers.add("localhost:" + rsPort); |
| | | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPort, "HistoricalCsnOrdering", 0, 1, |
| | | 0, 100, replServers, 1, 1000, 5000); |
| | | new ReplServerFakeConfiguration(rsPort, "HistoricalCsnOrdering", replicationDbImplementation, 0, |
| | | 1, 0, 100, replServers, 1, 1000, 5000); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | clearChangelogDB(replicationServer); |
| | | return replicationServer; |
| | |
| | | |
| | | String dir = "replicationServerFailoverTest" + serverId + suffix + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(port, dir, 0, serverId, 0, 100, |
| | | replServers); |
| | | new ReplServerFakeConfiguration(port, dir, replicationDbImplementation, 0, serverId, 0, |
| | | 100, replServers); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | |
| | | String dir = "replicationServerLoadBalancingTest" + rsIndex + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPort[rsIndex], dir, 0, rsIndex+501, 0, 100, |
| | | replServers, 1, 1000, 5000, weight); |
| | | new ReplServerFakeConfiguration(rsPort[rsIndex], dir, replicationDbImplementation, 0, rsIndex+501, 0, |
| | | 100, replServers, 1, 1000, 5000, weight); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | String dir = "replicationServerLoadBalancingTest" + rsIndex + testCase + "Db"; |
| | | return new ReplServerFakeConfiguration(rsPort[rsIndex], dir, 0, |
| | | rsIndex + 501, 0, 100, replServers, 1, 1000, 5000, weight); |
| | | return new ReplServerFakeConfiguration(rsPort[rsIndex], dir, replicationDbImplementation, |
| | | 0, rsIndex + 501, 0, 100, replServers, 1, 1000, 5000, weight); |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | String dir = "stateMachineTest" + RS1_ID + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rs1Port, dir, 0, RS1_ID, 0, 100, |
| | | replServers, 1, 1000, degradedStatusThreshold); |
| | | new ReplServerFakeConfiguration(rs1Port, dir, replicationDbImplementation, 0, RS1_ID, 0, |
| | | 100, replServers, 1, 1000, degradedStatusThreshold); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | |
| | | String dir = "topologyViewTest" + rsId + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPort, dir, 0, rsId, 0, 100, |
| | | replServers, groupId, 1000, 5000); |
| | | new ReplServerFakeConfiguration(rsPort, dir, replicationDbImplementation, 0, rsId, 0, |
| | | 100, replServers, groupId, 1000, 5000); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | |
| | | String dir = testName + serverId + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(port, dir, 0, serverId, 0, 100, |
| | | otherRsUrls, groupId, assuredTimeout, 5000); |
| | | new ReplServerFakeConfiguration(port, dir, replicationDbImplementation, 0, serverId, 0, |
| | | 100, otherRsUrls, groupId, assuredTimeout, 5000); |
| | | // No monitoring publisher to not interfere with some SocketTimeoutException |
| | | // expected at some points in these tests |
| | | conf.setMonitoringPeriod(0L); |
| | |
| | | // Create real RS |
| | | String dir = testName + RS1_ID + testCase + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPorts[0], dir, 0, RS1_ID, 0, 100, |
| | | new TreeSet<String>(), DEFAULT_GID, SMALL_TIMEOUT, 1); |
| | | new ReplServerFakeConfiguration(rsPorts[0], dir, replicationDbImplementation, 0, RS1_ID, 0, |
| | | 100, new TreeSet<String>(), DEFAULT_GID, SMALL_TIMEOUT, 1); |
| | | rs1 = new ReplicationServer(conf); |
| | | |
| | | /* |
| | |
| | | ReplServerFakeConfiguration conf1 = |
| | | new ReplServerFakeConfiguration( |
| | | replicationServerPort, "ExternalChangeLogTestDb", |
| | | 0, 71, 0, maxWindow, null); |
| | | replicationDbImplementation, 0, 71, 0, maxWindow, null); |
| | | conf1.setComputeChangeNumber(true); |
| | | |
| | | replicationServer = new ReplicationServer(conf1); |
| | |
| | | int chPort = getChangelogPort(changelogId); |
| | | String chDir = "monitorTest" + changelogId + suffix + "Db"; |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(chPort, chDir, 0, changelogId, 0, 100, |
| | | servers); |
| | | new ReplServerFakeConfiguration(chPort, chDir, replicationDbImplementation, 0, changelogId, 0, |
| | | 100, servers); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | Thread.sleep(1000); |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2007-2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS |
| | | * Portions Copyright 2013-2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.replication.server; |
| | | |
| | |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.server.ServerManagedObject; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.admin.std.server.ReplicationServerCfg; |
| | | import org.opends.server.types.DN; |
| | | |
| | |
| | | private long monitoringPeriod = 3000; |
| | | private boolean computeChangenumber; |
| | | |
| | | /** The DB implementation to use for replication changelog. */ |
| | | private final ReplicationDBImplementation dbImpl; |
| | | |
| | | /** |
| | | * Constructor without group id, assured info and weight |
| | | */ |
| | | public ReplServerFakeConfiguration( |
| | | int port, String dirName, int purgeDelay, int serverId, |
| | | int queueSize, int windowSize, SortedSet<String> servers) |
| | | int port, String dirName, ReplicationDBImplementation dbImpl, int purgeDelay, |
| | | int serverId, int queueSize, int windowSize, SortedSet<String> servers) |
| | | { |
| | | this.port = port; |
| | | this.dbImpl = dbImpl; |
| | | this.dirName = dirName != null ? dirName : "changelogDb"; |
| | | |
| | | if (purgeDelay == 0) |
| | |
| | | * Constructor with group id and assured info |
| | | */ |
| | | public ReplServerFakeConfiguration( |
| | | int port, String dirName, int purgeDelay, int serverId, |
| | | int queueSize, int windowSize, SortedSet<String> servers, |
| | | int groupId, long assuredTimeout, int degradedStatusThreshold) |
| | | int port, String dirName, ReplicationDBImplementation dbImpl, int purgeDelay, |
| | | int serverId, int queueSize, int windowSize, |
| | | SortedSet<String> servers, int groupId, long assuredTimeout, int degradedStatusThreshold) |
| | | { |
| | | this(port, dirName, purgeDelay, serverId, queueSize, windowSize, servers); |
| | | this(port, dirName, dbImpl, purgeDelay, serverId, queueSize, windowSize, servers); |
| | | this.groupId = groupId; |
| | | this.assuredTimeout = assuredTimeout; |
| | | this.degradedStatusThreshold = degradedStatusThreshold; |
| | |
| | | * Constructor with group id, assured info and weight |
| | | */ |
| | | public ReplServerFakeConfiguration( |
| | | int port, String dirName, int purgeDelay, int serverId, |
| | | int queueSize, int windowSize, SortedSet<String> servers, |
| | | int groupId, long assuredTimeout, int degradedStatusThreshold, int weight) |
| | | int port, String dirName, ReplicationDBImplementation dbImpl, int purgeDelay, |
| | | int serverId, int queueSize, int windowSize, |
| | | SortedSet<String> servers, int groupId, long assuredTimeout, int degradedStatusThreshold, int weight) |
| | | { |
| | | this(port, dirName, purgeDelay, serverId, queueSize, windowSize, servers, |
| | | groupId, assuredTimeout, degradedStatusThreshold); |
| | | this(port, dirName, dbImpl, purgeDelay, serverId, queueSize, windowSize, |
| | | servers, groupId, assuredTimeout, degradedStatusThreshold); |
| | | this.weight = weight; |
| | | } |
| | | |
| | |
| | | { |
| | | this.computeChangenumber = computeChangenumber; |
| | | } |
| | | |
| | | @Override |
| | | public ReplicationDBImplementation getReplicationDBImplementation() |
| | | { |
| | | return dbImpl; |
| | | } |
| | | } |
| | |
| | | // instantiate a Replication server using the first port number. |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration( |
| | | ports[0], null, 0, 1, 0, 0, null); |
| | | ports[0], null, replicationDbImplementation, 0, 1, 0, 0, null); |
| | | replicationServer = new ReplicationServer(conf); |
| | | |
| | | // Most of the configuration change are trivial to apply. |
| | |
| | | // connect to this new portnumber. |
| | | ReplServerFakeConfiguration newconf = |
| | | new ReplServerFakeConfiguration( |
| | | ports[1], null, 0, 1, 0, 0, null); |
| | | ports[1], null, replicationDbImplementation, 0, 1, 0, 0, null); |
| | | |
| | | replicationServer.applyConfigurationChange(newconf); |
| | | |
| | |
| | | "--provider-name", "Multimaster Synchronization", |
| | | "--set", "replication-db-directory:" + "replicationServerTestConfigureDb", |
| | | "--set", "replication-port:" + replicationServerPort, |
| | | "--set", "replication-db-implementation:" + replicationDbImplementation, |
| | | "--set", "replication-server-id:71"); |
| | | |
| | | for (SynchronizationProvider<?> provider : DirectoryServer |
| | |
| | | servers.add( |
| | | "localhost:" + ((i == 0) ? changelogPorts[1] : changelogPorts[0])); |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(changelogPorts[i], "replicationServerTestChangelogChainingDb"+i, 0, |
| | | changelogIds[i], 0, 100, servers); |
| | | new ReplServerFakeConfiguration(changelogPorts[i], "replicationServerTestChangelogChainingDb"+i, |
| | | replicationDbImplementation, 0, changelogIds[i], 0, 100, servers); |
| | | changelogs[i] = new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | SortedSet<String> servers = new TreeSet<String>(); |
| | | servers.add("localhost:" + changelogPorts[1]); |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(changelogPorts[0], "replicationServerTestChangelogChainingDb"+0, 0, |
| | | changelogIds[0], 0, 100, servers); |
| | | new ReplServerFakeConfiguration(changelogPorts[0], "replicationServerTestChangelogChainingDb"+0, replicationDbImplementation, |
| | | 0, changelogIds[0], 0, 100, servers); |
| | | changelogs[0] = new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | SortedSet<String> servers = new TreeSet<String>(); |
| | | servers.add("localhost:"+changelogPorts[0]); |
| | | ReplServerFakeConfiguration conf = new ReplServerFakeConfiguration( |
| | | changelogPorts[1], null, 0, changelogIds[1], 0, 100, null); |
| | | changelogPorts[1], null, replicationDbImplementation, 0, changelogIds[1], 0, 100, null); |
| | | changelogs[1] = new ReplicationServer(conf); |
| | | |
| | | // Connect broker 2 to changelog2 |
| | |
| | | if (i==0) |
| | | servers.add("localhost:" + changelogPorts[1]); |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(changelogPorts[i], "replicationServerTestReplicationServerConnectedDb"+i, 0, |
| | | changelogIds[i], 0, 100, servers); |
| | | new ReplServerFakeConfiguration(changelogPorts[i], "replicationServerTestReplicationServerConnectedDb"+i, replicationDbImplementation, |
| | | 0, changelogIds[i], 0, 100, servers); |
| | | changelogs[i] = new ReplicationServer(conf); |
| | | } |
| | | |
| | |
| | | SortedSet<String> servers = new TreeSet<String>(); |
| | | // Configure replicationServer[0] to be disconnected from ReplicationServer[1] |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(changelogPorts[0], "changelogDb0", 0, |
| | | changelogIds[0], 0, 100, servers); |
| | | new ReplServerFakeConfiguration(changelogPorts[0], "changelogDb0", replicationDbImplementation, |
| | | 0, changelogIds[0], 0, 100, servers); |
| | | changelogs[0].applyConfigurationChange(conf) ; |
| | | |
| | | // The link between RS[0] & RS[1] should be destroyed by the new configuration. |
| | |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | import org.opends.server.replication.common.CSN; |
| | | import org.opends.server.replication.common.MultiDomainServerState; |
| | |
| | | import org.opends.server.replication.server.changelog.api.DBCursor; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.BeforeMethod; |
| | | import org.testng.annotations.Test; |
| | | |
| | |
| | | new MultiDomainServerState(); |
| | | private final List<String> cookies = new ArrayList<String>(); |
| | | |
| | | private static final ReplicationDBImplementation previousDBImpl = replicationDbImplementation; |
| | | |
| | | @BeforeClass |
| | | public void setDBImpl() |
| | | { |
| | | setReplicationDBImplementation(ReplicationDBImplementation.JE); |
| | | } |
| | | |
| | | @AfterClass |
| | | public void resetDBImplToPrevious() |
| | | { |
| | | setReplicationDBImplementation(previousDBImpl); |
| | | } |
| | | |
| | | @BeforeMethod |
| | | public void clearCookie() |
| | | { |
| | |
| | | TestCaseUtils.startServer(); |
| | | final int port = TestCaseUtils.findFreePort(); |
| | | final ReplServerFakeConfiguration cfg = |
| | | new ReplServerFakeConfiguration(port, null, 0, 2, 0, 100, null); |
| | | new ReplServerFakeConfiguration(port, null, ReplicationDBImplementation.JE, 0, 2, 0, 100, null); |
| | | cfg.setComputeChangeNumber(true); |
| | | return new ReplicationServer(cfg); |
| | | } |
| | |
| | | |
| | | import org.assertj.core.api.SoftAssertions; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.ReplicationServerCfgDefn.ReplicationDBImplementation; |
| | | import org.opends.server.admin.std.server.ReplicationServerCfg; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | |
| | | import org.opends.server.replication.server.changelog.api.DBCursor; |
| | | import org.opends.server.replication.server.changelog.api.DBCursor.PositionStrategy; |
| | | import org.opends.server.types.DN; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | |
| | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | private DN TEST_ROOT_DN; |
| | | |
| | | private static final ReplicationDBImplementation previousDBImpl = replicationDbImplementation; |
| | | |
| | | @BeforeClass |
| | | public void setDBImpl() |
| | | { |
| | | setReplicationDBImplementation(ReplicationDBImplementation.JE); |
| | | } |
| | | |
| | | @AfterClass |
| | | public void resetDBImplToPrevious() |
| | | { |
| | | setReplicationDBImplementation(previousDBImpl); |
| | | } |
| | | |
| | | /** |
| | | * Utility - log debug message - highlight it is from the test and not |
| | | * from the server code. Makes easier to observe the test steps. |
| | |
| | | } |
| | | } |
| | | |
| | | static CSN[] newCSNs(int serverId, long timestamp, int number) |
| | | { |
| | | CSNGenerator gen = new CSNGenerator(serverId, timestamp); |
| | | CSN[] csns = new CSN[number]; |
| | | for (int i = 0; i < csns.length; i++) |
| | | { |
| | | csns[i] = gen.newCSN(); |
| | | } |
| | | return csns; |
| | | } |
| | | |
| | | private ReplicationServer configureReplicationServer(int windowSize, int queueSize) |
| | | throws IOException, ConfigException |
| | | { |
| | | final int changelogPort = findFreePort(); |
| | | final ReplicationServerCfg conf = |
| | | new ReplServerFakeConfiguration(changelogPort, null, ReplicationDBImplementation.JE, 0, 2, queueSize, windowSize, null); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | | private JEReplicaDB newReplicaDB(ReplicationServer rs) throws Exception |
| | | { |
| | | final JEChangelogDB changelogDB = (JEChangelogDB) rs.getChangelogDB(); |
| | | return changelogDB.getOrCreateReplicaDB(TEST_ROOT_DN, 1, rs).getFirst(); |
| | | } |
| | | |
| | | private File createCleanDir() throws IOException |
| | | { |
| | | String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT); |
| | | String path = System.getProperty(TestCaseUtils.PROPERTY_BUILD_DIR, buildRoot |
| | | + File.separator + "build"); |
| | | path = path + File.separator + "unit-tests" + File.separator + "JEReplicaDB"; |
| | | final File testRoot = new File(path); |
| | | TestCaseUtils.deleteDirectory(testRoot); |
| | | testRoot.mkdirs(); |
| | | return testRoot; |
| | | } |
| | | |
| | | private void assertFoundInOrder(JEReplicaDB replicaDB, CSN... csns) throws Exception |
| | | { |
| | | if (csns.length == 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | assertFoundInOrder(replicaDB, AFTER_MATCHING_KEY, csns); |
| | | assertFoundInOrder(replicaDB, ON_MATCHING_KEY, csns); |
| | | } |
| | | |
| | | /** |
| | | * Test the feature of clearing a JEReplicaDB used by a replication server. |
| | | * The clear feature is used when a replication server receives a request to |
| | |
| | | return csns; |
| | | } |
| | | |
| | | private ReplicationServer configureReplicationServer(int windowSize, int queueSize) |
| | | throws IOException, ConfigException |
| | | { |
| | | final int changelogPort = findFreePort(); |
| | | final ReplicationServerCfg conf = new ReplServerFakeConfiguration( |
| | | changelogPort, null, 0, 2, queueSize, windowSize, null); |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | | private JEReplicaDB newReplicaDB(ReplicationServer rs) throws Exception |
| | | { |
| | | final JEChangelogDB changelogDB = (JEChangelogDB) rs.getChangelogDB(); |
| | | return changelogDB.getOrCreateReplicaDB(TEST_ROOT_DN, 1, rs).getFirst(); |
| | | } |
| | | |
| | | private File createCleanDir() throws IOException |
| | | { |
| | | String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT); |
| | | String path = System.getProperty(TestCaseUtils.PROPERTY_BUILD_DIR, buildRoot |
| | | + File.separator + "build"); |
| | | path = path + File.separator + "unit-tests" + File.separator + "JEReplicaDB"; |
| | | final File testRoot = new File(path); |
| | | TestCaseUtils.deleteDirectory(testRoot); |
| | | testRoot.mkdirs(); |
| | | return testRoot; |
| | | } |
| | | |
| | | private void assertFoundInOrder(JEReplicaDB replicaDB, CSN... csns) throws Exception |
| | | { |
| | | if (csns.length == 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | assertFoundInOrder(replicaDB, AFTER_MATCHING_KEY, csns); |
| | | assertFoundInOrder(replicaDB, ON_MATCHING_KEY, csns); |
| | | } |
| | | |
| | | private void assertFoundInOrder(JEReplicaDB replicaDB, |
| | | final PositionStrategy positionStrategy, CSN... csns) throws ChangelogException |
| | | { |
| | |
| | | SortedSet<String> replServers) throws Exception |
| | | { |
| | | ReplServerFakeConfiguration cfg = |
| | | new ReplServerFakeConfiguration(replicationPort, dirName, 0, serverId, |
| | | 0, windowSize, replServers); |
| | | new ReplServerFakeConfiguration(replicationPort, dirName, replicationDbImplementation, 0, |
| | | serverId, 0, windowSize, replServers); |
| | | return new ReplicationServer(cfg); |
| | | } |
| | | |