From 76ebd1ad82e2a1fc421519f09c62b948e9376e8a Mon Sep 17 00:00:00 2001
From: pgamba <pgamba@localhost>
Date: Tue, 06 Oct 2009 12:34:32 +0000
Subject: [PATCH] Entry attributes for ECL - Protocol V4
---
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 309 insertions(+), 28 deletions(-)
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
index 1c88152..3a644bb 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
@@ -27,9 +27,8 @@
package org.opends.server.replication;
import static org.opends.server.TestCaseUtils.TEST_ROOT_DN_STRING;
-import static org.opends.server.loggers.ErrorLogger.logError;
-import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.replication.protocol.OperationContext.SYNCHROCONTEXT;
import static org.opends.server.util.StaticUtils.createEntry;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
@@ -45,17 +44,16 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
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;
@@ -66,8 +64,10 @@
import org.opends.server.controls.PersistentSearchChangeType;
import org.opends.server.controls.PersistentSearchControl;
import org.opends.server.core.AddOperationBasis;
+import org.opends.server.core.DeleteOperationBasis;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperationBasis;
+import org.opends.server.core.ModifyOperationBasis;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.plugins.InvocationCounterPlugin;
import org.opends.server.protocols.asn1.ASN1Exception;
@@ -103,7 +103,6 @@
import org.opends.server.replication.protocol.StartECLSessionMsg;
import org.opends.server.replication.protocol.UpdateMsg;
import org.opends.server.replication.server.DraftCNDbHandler;
-import org.opends.server.replication.server.ExternalChangeLogSessionImpl;
import org.opends.server.replication.server.ReplServerFakeConfiguration;
import org.opends.server.replication.server.ReplicationServer;
import org.opends.server.replication.server.ReplicationServerDomain;
@@ -111,6 +110,7 @@
import org.opends.server.tools.LDAPSearch;
import org.opends.server.tools.LDAPWriter;
import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.ByteString;
@@ -157,6 +157,9 @@
private static final String TEST_ROOT_DN_STRING2 = "o=test2";
private static final String TEST_BACKEND_ID2 = "test2";
+ private static final String TEST_ROOT_DN_STRING3 = "o=test3";
+ private static final String TEST_BACKEND_ID3 = "test3";
+
// The LDAPStatistics object associated with the LDAP connection handler.
private LDAPStatistics ldapStatistics;
@@ -206,8 +209,9 @@
@Test(enabled=true)
public void ECLReplicationServerTest()
{
- // --
+ // ***********************************************
// First set of test are in the cookie mode
+ // ***********************************************
// Test that private backend is excluded from ECL
ECLOnPrivateBackend();replicationServer.clearDb();
@@ -250,7 +254,6 @@
// TODO:ECL Test SEARCH abandon and check everything shutdown and cleaned
// TODO:ECL Test PSEARCH abandon and check everything shutdown and cleaned
// TODO:ECL Test invalid DN in cookie returns UNWILLING + message
- // TODO:ECL Test notif control returned contains the cookie
// TODO:ECL Test the attributes list and values returned in ECL entries
// TODO:ECL Test search -s base, -s one
@@ -262,8 +265,9 @@
// optimize the request.
ECLFilterTest();
- // --
+ // ***********************************************
// Second set of test are in the draft compat mode
+ // ***********************************************
// Empty replication changelog
ECLCompatEmpty();
@@ -309,6 +313,10 @@
// Test simultaneous persistent searches in draft compat mode.
ECLSimultaneousPsearches();replicationServer.clearDb();
+ // ***********************************************
+ // Entry attributes
+ // ***********************************************
+ ECLIncludeAttributes();replicationServer.clearDb();
}
//=======================================================
@@ -391,7 +399,6 @@
server1.stop();
server2.stop();
server3.stop();
- sleep(500);
debugInfo(tn, "Ending test successfully\n\n");
}
catch(Exception e)
@@ -484,8 +491,7 @@
// clean
serverECL.stop();
server01.stop();
- server02.stop();
- sleep(2000);
+ server02.stop();
debugInfo(tn, "Ending test successfully");
}
catch(Exception e)
@@ -605,7 +611,8 @@
// Initialize a second test backend o=test2, in addtion to o=test
// Configure replication on this backend
// Add the root entry in the backend
- Backend backend2 = initializeTestBackend2(false);
+ Backend backend2 = initializeTestBackend(false, TEST_ROOT_DN_STRING2,
+ TEST_BACKEND_ID2);
DN baseDn2 = DN.decode(TEST_ROOT_DN_STRING2);
SortedSet<String> replServers = new TreeSet<String>();
replServers.add("localhost:"+replicationServerPort);
@@ -647,16 +654,25 @@
assertEquals(searchOp.getResultCode(), ResultCode.SUCCESS,
searchOp.getErrorMessage().toString() + searchOp.getAdditionalLogMessage());
LinkedList<SearchResultEntry> entries = searchOp.getSearchEntries();
+ assertEquals(entries.size(),2, "Entries number returned by search");
assertTrue(entries != null);
if (entries != null)
+ {
+ int i = 0;
for (SearchResultEntry resultEntry : entries)
{
+ i++;
// Expect
debugInfo(tn, "Entry returned when test2 is public =" +
resultEntry.toLDIFString());
+
+ // Test entry attributes
+ //if (i==2)
+ //{
+ // checkPossibleValues(resultEntry,"targetobjectclass","top","organization");
+ //}
}
- assertEquals(entries.size(),2, "Entries number returned by search");
-
+ }
//
// Set the backend private and do again a search on ECL that should
// now not return the entry
@@ -732,7 +748,8 @@
try
{
// Initialize a second test backend
- Backend backend2 = initializeTestBackend2(true);
+ Backend backend2 = initializeTestBackend(true,
+ TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2);
//
LDIFWriter ldifWriter = getLDIFWriter();
@@ -1485,6 +1502,22 @@
}
}
+ private static String getAttributeValue(Entry entry, String attrName)
+ {
+ AttributeValue av = null;
+ try
+ {
+ List<Attribute> attrs = entry.getAttribute(attrName);
+ Attribute a = attrs.iterator().next();
+ av = a.iterator().next();
+ return av.toString();
+ }
+ catch(Exception e)
+ {
+ }
+ return null;
+ }
+
private static void checkPossibleValues(Entry entry, String attrName,
String expectedValue1, String expectedValue2)
{
@@ -1511,6 +1544,36 @@
}
}
+ private static void checkValues(Entry entry, String attrName,
+ Set<String> expectedValues)
+ {
+ AttributeValue av = null;
+ int i=0;
+ try
+ {
+ List<Attribute> attrs = entry.getAttribute(attrName);
+ Attribute a;
+ Iterator<Attribute> iat = attrs.iterator();
+ while ((a=iat.next())!=null)
+ {
+ Iterator<AttributeValue> iatv = a.iterator();
+ while ((av = iatv.next())!=null)
+ {
+ String encodedValue = av.toString();
+ assertTrue(
+ expectedValues.contains(encodedValue),
+ "In entry " + entry + " attr <" + attrName + "> equals " +
+ av + " instead of one of the expected values " + expectedValues);
+ i++;
+ }
+ }
+ }
+ catch(NoSuchElementException e)
+ {
+ assertTrue(i==expectedValues.size());
+ }
+ }
+
/**
* Test persistent search
*/
@@ -2385,23 +2448,26 @@
*/
private void debugInfo(String tn, String s)
{
- //if (debugEnabled())
+ if (debugEnabled())
{
- logError(Message.raw(Category.SYNC, Severity.NOTICE,
- "** TEST " + tn + " ** " + s));
- //TRACER.debugInfo("** TEST " + tn + " ** " + s);
+// logError(Message.raw(Category.SYNC, Severity.NOTICE,
+// "** TEST " + tn + " ** " + s));
+ TRACER.debugInfo("** TEST " + tn + " ** " + s);
}
}
/**
* Utility - create a second backend in order to test ECL with 2 suffixes.
*/
- private static Backend initializeTestBackend2(boolean createBaseEntry)
+ private static Backend initializeTestBackend(
+ boolean createBaseEntry,
+ String rootDN,
+ String backendId)
throws IOException, InitializationException, ConfigException,
DirectoryException
{
- DN baseDN = DN.decode(TEST_ROOT_DN_STRING2);
+ DN baseDN = DN.decode(rootDN);
// Retrieve backend. Warning: it is important to perform this each time,
// because a test may have disabled then enabled the backend (i.e a test
@@ -2410,12 +2476,12 @@
// to memory backend must be invalidated. So to prevent this problem, we
// retrieve the memory backend reference each time before cleaning it.
MemoryBackend memoryBackend =
- (MemoryBackend)DirectoryServer.getBackend(TEST_BACKEND_ID2);
+ (MemoryBackend)DirectoryServer.getBackend(backendId);
if (memoryBackend == null)
{
memoryBackend = new MemoryBackend();
- memoryBackend.setBackendID(TEST_BACKEND_ID2);
+ memoryBackend.setBackendID(backendId);
memoryBackend.setBaseDNs(new DN[] {baseDN});
memoryBackend.initializeBackend();
DirectoryServer.registerBackend(memoryBackend);
@@ -2447,7 +2513,8 @@
try
{
// Initialize a second test backend
- Backend backend2 = initializeTestBackend2(true);
+ Backend backend2 = initializeTestBackend(true, TEST_ROOT_DN_STRING2,
+ TEST_BACKEND_ID2);
// --
ReplicationBroker s1test = openReplicationSession(
@@ -2862,8 +2929,6 @@
}
}
assertEquals(searchOp.getSearchEntries().size(), 4);
-
-
}
catch(Exception e)
{
@@ -3410,4 +3475,220 @@
debugInfo(tn, "Ending test with success");
}
+ /**
+ * Test ECl entry attributes, and there configuration.
+ *
+ */
+ private void ECLIncludeAttributes()
+ {
+ String tn = "ECLIncludeAttributes";
+ debugInfo(tn, "Starting test\n\n");
+ try
+ {
+ // Initialize a second test backend o=test2, in addtion to o=test
+ // Configure replication on this backend
+ // Add the root entry in the backend
+ Backend backend2 = initializeTestBackend(false,
+ TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2);
+ DN baseDn2 = DN.decode(TEST_ROOT_DN_STRING2);
+ SortedSet<String> replServers = new TreeSet<String>();
+ replServers.add("localhost:"+replicationServerPort);
+ DomainFakeCfg domainConf =
+ new DomainFakeCfg(baseDn2, (short) 1702, replServers);
+ SortedSet<String> includeAttributes = new TreeSet<String>();
+ includeAttributes.add("sn");
+ domainConf.setEclIncludes(includeAttributes);
+ LDAPReplicationDomain domain2 = MultimasterReplication.createNewDomain(domainConf);
+ SynchronizationProvider replicationPlugin2 = new MultimasterReplication();
+ replicationPlugin2.completeSynchronizationProvider();
+
+ Backend backend3 = initializeTestBackend(false,
+ TEST_ROOT_DN_STRING3, TEST_BACKEND_ID3);
+ DN baseDn3 = DN.decode(TEST_ROOT_DN_STRING3);
+ domainConf =
+ new DomainFakeCfg(baseDn3, (short) 1703, replServers);
+ includeAttributes = new TreeSet<String>();
+ includeAttributes.add("objectclass");
+ domainConf.setEclIncludes(includeAttributes);
+ LDAPReplicationDomain domain3 = MultimasterReplication.createNewDomain(domainConf);
+ SynchronizationProvider replicationPlugin3 = new MultimasterReplication();
+ replicationPlugin3.completeSynchronizationProvider();
+
+ domainConf =
+ new DomainFakeCfg(baseDn2, (short) 1704, replServers);
+ includeAttributes = new TreeSet<String>();
+ includeAttributes.add("cn");
+ domainConf.setEclIncludes(includeAttributes);
+ LDAPReplicationDomain domain21 = MultimasterReplication.createNewDomain(domainConf);
+
+ Set<String> attrList = new HashSet<String>();
+ attrList.add(new String("cn"));
+ ReplicationBroker server01 = openReplicationSession(
+ DN.decode(TEST_ROOT_DN_STRING2), (short) 1206,
+ 100, replicationServerPort,
+ 1000, true, -1 , domain21);
+
+ sleep(1000);
+
+ Entry e2 = createEntry(baseDn2);
+ addEntry(e2);
+
+ Entry e3 = createEntry(baseDn3);
+ addEntry(e3);
+
+ String lentry = new String(
+ "dn: cn=Fiona Jensen," + TEST_ROOT_DN_STRING2 + "\n"
+ + "objectclass: top\n"
+ + "objectclass: person\n"
+ + "objectclass: organizationalPerson\n"
+ + "objectclass: inetOrgPerson\n"
+ + "cn: Fiona Jensen\n"
+ + "sn: Jensen\n"
+ + "uid: fiona\n"
+ + "telephonenumber: 12121212");
+
+ Entry uentry1 = TestCaseUtils.entryFromLdifString(lentry);
+ addEntry(uentry1);
+
+ lentry = new String(
+ "dn: cn=Robert Hue," + TEST_ROOT_DN_STRING3 + "\n"
+ + "objectclass: top\n"
+ + "objectclass: person\n"
+ + "objectclass: organizationalPerson\n"
+ + "objectclass: inetOrgPerson\n"
+ + "cn: Robert Hue\n"
+ + "sn: Robby\n"
+ + "uid: robert\n"
+ + "telephonenumber: 131313");
+ Entry uentry2 = TestCaseUtils.entryFromLdifString(lentry);
+ addEntry(uentry2);
+
+ AttributeBuilder builder = new AttributeBuilder("sn");
+ builder.add("newsn");
+ Modification mod =
+ new Modification(ModificationType.REPLACE, builder.toAttribute());
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add(mod);
+
+ ModifyOperationBasis modOpBasis =
+ new ModifyOperationBasis(connection, 1, 1, null, uentry1.getDN(), mods);
+ modOpBasis.run();
+
+ builder = new AttributeBuilder("telephonenumber");
+ builder.add("555555");
+ mod =
+ new Modification(ModificationType.REPLACE, builder.toAttribute());
+ mods = new ArrayList<Modification>();
+ mods.add(mod);
+
+ modOpBasis =
+ new ModifyOperationBasis(connection, 1, 1, null, uentry2.getDN(), mods);
+ modOpBasis.run();
+
+ ModifyDNOperationBasis modDNOp = new ModifyDNOperationBasis(connection,
+ InternalClientConnection.nextOperationID(),
+ InternalClientConnection.nextMessageID(),
+ null,
+ DN.decode("cn=Robert Hue," + TEST_ROOT_DN_STRING3),
+ RDN.decode("cn=Robert Hue2"), true,
+ DN.decode(TEST_ROOT_DN_STRING3));
+ modDNOp.run();
+ assertEquals(modDNOp.getResultCode(), ResultCode.SUCCESS,
+ modDNOp.getErrorMessage().toString() + modDNOp.getAdditionalLogMessage());
+
+ DeleteOperationBasis delOp = new DeleteOperationBasis(connection,
+ InternalClientConnection.nextOperationID(),
+ InternalClientConnection.nextMessageID(), null,
+ DN.decode("cn=Robert Hue2," + TEST_ROOT_DN_STRING3));
+ delOp.run();
+ assertEquals(delOp.getResultCode(), ResultCode.SUCCESS,
+ delOp.getErrorMessage().toString() + delOp.getAdditionalLogMessage());
+
+ sleep(400);
+
+ // Search on ECL from start on all suffixes
+ String cookie = "";
+ ExternalChangelogRequestControl control =
+ new ExternalChangelogRequestControl(true,
+ new MultiDomainServerState(cookie));
+ ArrayList<Control> controls = new ArrayList<Control>(0);
+ controls.add(control);
+ LinkedHashSet<String> attributes = new LinkedHashSet<String>();
+ attributes.add("+");
+ attributes.add("*");
+
+
+ debugInfo(tn, "Search with cookie=" + cookie);
+ InternalSearchOperation searchOp = connection.processSearch(
+ ByteString.valueOf("cn=changelog"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ 0, // Size limit
+ 0, // Time limit
+ false, // Types only
+ LDAPFilter.decode("(targetDN=*)"),
+ attributes,
+ controls,
+ null);
+
+ sleep(500);
+
+ // Expect SUCCESS and root entry returned
+ assertEquals(searchOp.getResultCode(), ResultCode.SUCCESS,
+ searchOp.getErrorMessage().toString() + searchOp.getAdditionalLogMessage());
+ LinkedList<SearchResultEntry> entries = searchOp.getSearchEntries();
+
+
+ assertEquals(entries.size(),8, "Entries number returned by search");
+ assertTrue(entries != null);
+
+ if (entries != null)
+ {
+ for (SearchResultEntry resultEntry : entries)
+ {
+ // Expect
+ debugInfo(tn, "Entry returned =" + resultEntry.toLDIFString());
+
+ String targetdn = getAttributeValue(resultEntry, "targetdn");
+ if ((targetdn.endsWith("cn=robert hue,o=test3"))
+ ||(targetdn.endsWith("cn=robert hue2,o=test3")))
+ {
+ HashSet<String> eoc = new HashSet<String>();
+ eoc.add("person");eoc.add("inetOrgPerson");eoc.add("organizationalPerson");eoc.add("top");
+ checkValues(resultEntry,"targetobjectclass",eoc);
+ }
+ if (targetdn.endsWith("cn=fiona jensen,o=test2"))
+ {
+ checkValue(resultEntry,"targetsn","jensen");
+ checkValue(resultEntry,"targetcn","Fiona Jensen");
+ }
+ }
+ }
+ server01.stop();
+
+ // Cleaning
+ if (domain2 != null)
+ MultimasterReplication.deleteDomain(baseDn2);
+ if (replicationPlugin2 != null)
+ DirectoryServer.deregisterSynchronizationProvider(replicationPlugin2);
+ removeTestBackend2(backend2);
+
+ if (domain3 != null)
+ MultimasterReplication.deleteDomain(baseDn3);
+ if (replicationPlugin3 != null)
+ DirectoryServer.deregisterSynchronizationProvider(replicationPlugin3);
+ removeTestBackend2(backend3);
+
+ }
+ catch(Exception e)
+ {
+ fail("Ending "+tn+" test with exception:\n"
+ + stackTraceToSingleLineString(e));
+ }
+ finally
+ {
+
+ }
+ debugInfo(tn, "Ending test with success");
+ }
}
\ No newline at end of file
--
Gitblit v1.10.0