| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | |
| | | private long checksum = 0L; |
| | | |
| | | /** |
| | | * This is the generation id for an empty backend. |
| | | */ |
| | | public static final long EMPTY_BACKEND_GENERATION_ID = 48L; |
| | | |
| | | /** |
| | | * Update the checksum with one added byte. |
| | | */ |
| | | private void updateWithOneByte(byte b) |
| | | { |
| | | checksum += (long) b; |
| | | /** |
| | | * The "end of line" code is CRLF under windows but LF on UNIX. So to get |
| | | * the same checksum value on every platforms, we always exclude the CR and |
| | | * LF characters from the computation. |
| | | */ |
| | | if ((b != 0x0D) && (b != 0x0A)) // CR=0D and LF=0A |
| | | { |
| | | checksum += (long) b; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public long getValue() |
| | | { |
| | | return checksum; |
| | | if (checksum != 0L) |
| | | { |
| | | return checksum; |
| | | } else |
| | | { |
| | | // Computing an empty backend writes the number of entries (0) only, which |
| | | // will not be added to the checksum as no entries will follow. To treat |
| | | // this special case, and to keep consistency with old versions, in that |
| | | // case we hardcode and return the generation id value for an empty |
| | | // backend. |
| | | return EMPTY_BACKEND_GENERATION_ID; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | import java.util.concurrent.BlockingQueue; |
| | | import java.util.concurrent.TimeoutException; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.zip.CheckedOutputStream; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.messages.Message; |
| | |
| | | { |
| | | long genID = 0; |
| | | Backend backend = retrievesBackend(this.baseDn); |
| | | long bec = backend.numSubordinates(baseDn, true) + 1; |
| | | long entryCount = (bec<1000?bec:1000); |
| | | long numberOfEntries = backend.numSubordinates(baseDn, true) + 1; |
| | | long entryCount = ( (numberOfEntries < 1000 )? numberOfEntries : 1000); |
| | | |
| | | // Acquire a shared lock for the backend. |
| | | try |
| | |
| | | ResultCode.OTHER, message, null); |
| | | } |
| | | |
| | | OutputStream os; |
| | | OutputStream os = null; |
| | | ReplLDIFOutputStream ros = null; |
| | | |
| | | if (checksumOutput) |
| | | { |
| | | ros = new ReplLDIFOutputStream(this, entryCount); |
| | | os = new CheckedOutputStream(ros, new GenerationIdChecksum()); |
| | | os = (OutputStream)new ReplLDIFOutputStream(entryCount); |
| | | ros = (ReplLDIFOutputStream)os; |
| | | try |
| | | { |
| | | os.write((Long.toString(backend.numSubordinates(baseDn, true) + 1)). |
| | | os.write((Long.toString(numberOfEntries)). |
| | | getBytes()); |
| | | } |
| | | catch(Exception e) |
| | |
| | | |
| | | if (checksumOutput) |
| | | { |
| | | genID = |
| | | ((CheckedOutputStream)os).getChecksum().getValue(); |
| | | genID = ros.getChecksumValue(); |
| | | } |
| | | |
| | | // Release the shared lock on the backend. |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | |
| | | import java.io.IOException; |
| | | import java.io.OutputStream; |
| | | |
| | | import org.opends.server.replication.service.ReplicationDomain; |
| | | import org.opends.server.util.ServerConstants; |
| | | |
| | | /** |
| | | * This class creates an output stream that can be used to export entries |
| | | * to a synchonization domain. |
| | | * to a synchronization domain. |
| | | */ |
| | | public class ReplLDIFOutputStream |
| | | extends OutputStream |
| | | { |
| | | // The synchronization domain on which the export is done |
| | | ReplicationDomain domain; |
| | | |
| | | // The number of entries to be exported |
| | | long numEntries; |
| | | |
| | |
| | | private long numExportedEntries; |
| | | String entryBuffer = ""; |
| | | |
| | | // The checksum for computing the generation id |
| | | private GenerationIdChecksum checkSum = new GenerationIdChecksum(); |
| | | |
| | | /** |
| | | * Creates a new ReplLDIFOutputStream related to a replication |
| | | * domain. |
| | | * |
| | | * @param domain The replication domain |
| | | * @param numEntries The max number of entry to process. |
| | | */ |
| | | public ReplLDIFOutputStream(ReplicationDomain domain, long numEntries) |
| | | public ReplLDIFOutputStream(long numEntries) |
| | | { |
| | | this.domain = domain; |
| | | this.numEntries = numEntries; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Get the value of the underlying checksum. |
| | | * @return The value of the underlying checksum |
| | | */ |
| | | public long getChecksumValue() |
| | | { |
| | | return checkSum.getValue(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void write(byte b[], int off, int len) throws IOException |
| | |
| | | throw(new IOException()); |
| | | } |
| | | |
| | | // Add the entry bytes to the checksum |
| | | byte[] entryBytes = entryBuffer.getBytes(); |
| | | checkSum.update(entryBytes, 0, entryBytes.length); |
| | | |
| | | numExportedEntries++; |
| | | entryBuffer = ""; |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2009 Sun Microsystems, Inc. |
| | | * Copyright 2007-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication; |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | private final long CLEAN_DB_GENERATION_ID = 7933L; |
| | | private final long CLEAN_DB_GENERATION_ID = 7883L; |
| | | /** |
| | | * Clean the database and replace with a single entry. |
| | | * |
| | |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.messages.Category; |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.api.Backend; |
| | | import org.opends.server.api.ConnectionHandler; |
| | |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | |
| | | |
| | | /** |
| | |
| | | |
| | | try |
| | | { |
| | | // create 2 reguler brokers on the 2 suffixes |
| | | // create 2 regular brokers on the 2 suffixes |
| | | server01 = openReplicationSession( |
| | | DN.decode(TEST_ROOT_DN_STRING), 1201, |
| | | 100, replicationServerPort, |
| | |
| | | makeBrokerPublishEntries(server2, server2ID, server1ID, server2ID); |
| | | |
| | | // wait until the replication domain has expected generationID |
| | | // this should indicate that the import occured correctly. |
| | | // this should indicate that the import occurred correctly. |
| | | final long EXPECTED_GENERATION_ID = 52955L; |
| | | long readGenerationId = -1L; |
| | | for (int count = 0; count < 120; count++) |
| | | { |
| | | if (replDomain.getGenerationID() == 53235) |
| | | readGenerationId = replDomain.getGenerationID(); |
| | | if ( readGenerationId == EXPECTED_GENERATION_ID) |
| | | break; |
| | | log(testCase + " genId=" + replDomain.getGenerationID()); |
| | | log(testCase + " genId=" + readGenerationId); |
| | | Thread.sleep(1000); |
| | | } |
| | | |
| | | if (replDomain.getGenerationID() != 53235) |
| | | if (readGenerationId != EXPECTED_GENERATION_ID) |
| | | { |
| | | fail(testCase + " Import success waited longer than expected \n" + |
| | | TestCaseUtils.threadStacksToString()); |
| | | } |
| | | |
| | | |
| | | // Test that entries have been imported in S1 |
| | | testEntriesInDb(); |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication; |
| | | |
| | |
| | | import org.opends.server.protocols.internal.InternalSearchOperation; |
| | | import org.opends.server.protocols.ldap.LDAPFilter; |
| | | import org.opends.server.replication.common.ServerState; |
| | | import org.opends.server.replication.plugin.GenerationIdChecksum; |
| | | import org.opends.server.replication.plugin.LDAPReplicationDomain; |
| | | import org.opends.server.replication.plugin.MultimasterReplication; |
| | | import org.opends.server.replication.plugin.PersistentServerState; |
| | |
| | | // This matches the backend obtained calling: |
| | | // TestCaseUtils.initializeTestBackend(true). |
| | | // (using the default TestCaseUtils.TEST_ROOT_DN_STRING suffix) |
| | | protected static final long TEST_DN_WITH_ROOT_ENTRY_GENID = 5095L; |
| | | protected static final long TEST_DN_WITH_ROOT_ENTRY_GENID = 5055L; |
| | | |
| | | /** |
| | | * Generation id for a fully empty domain. |
| | | */ |
| | | public static final long EMPTY_DN_GENID = 48L; |
| | | public static final long EMPTY_DN_GENID = GenerationIdChecksum.EMPTY_BACKEND_GENERATION_ID; |
| | | |
| | | /** |
| | | * The internal connection used for operation |
| | |
| | | /** |
| | | * Retrieves the domain associated to the baseDn, and the value of the generationId |
| | | * of this domain. If the domain does not exist, returns the default hard-coded\ |
| | | * value of the generationId corresponding to 'no entry'. |
| | | * value of the generationId corresponding to test backend with its default |
| | | * initial o=test root root entry. |
| | | * |
| | | * @param baseDn The baseDn for which we want the generationId |
| | | * @return The value of the generationId. |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | |
| | | GenerationIdChecksum checksum = new GenerationIdChecksum(); |
| | | |
| | | // Default value test |
| | | assertEquals(checksum.getValue(), 0L); |
| | | assertEquals(checksum.getValue(), GenerationIdChecksum.EMPTY_BACKEND_GENERATION_ID); |
| | | |
| | | // Update method simple version test |
| | | checksum.update(3); |
| | |
| | | |
| | | // Reset test |
| | | checksum.reset(); |
| | | assertEquals(checksum.getValue(), 0L); |
| | | assertEquals(checksum.getValue(), GenerationIdChecksum.EMPTY_BACKEND_GENERATION_ID); |
| | | |
| | | // Update method simple version test, again |
| | | checksum.update(101); |
| | |
| | | protected Object[][] arrayUpdateProvider() |
| | | { |
| | | return new Object[][] { |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 10, 55}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 10, 45}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 1, 1}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 2, 3}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 3, 6}, |
| | |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 3, 3, 15}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 7, 1, 8}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 7, 2, 17}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 7, 3, 27}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9, 1, 10}, |
| | | {new byte[]{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 0, 10, 65}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 7, 3, 17}, |
| | | {new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 9, 2, 11}, |
| | | {new byte[]{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 0, 10, 55}, |
| | | {new byte[]{118, 119, 120, 121, 122, 123, 124, 125, 126, 127}, 0, 10, 1225}}; |
| | | } |
| | | |