attributes.add("+");
attributes.add("*");
ExternalChangelogRequestControl control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(cookie));
ArrayList<Control> controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with cookie=" + cookie);
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=*"+tn+"*)"),
attributes,
controls,
null);
// We expect SUCCESS and the 4th change
waitOpResult(searchOp, ResultCode.SUCCESS);
entries = searchOp.getSearchEntries();
cookie="";
if (entries != null)
{
for (SearchResultEntry entry : entries)
{
debugInfo(tn, "Result entry=\n" + entry.toLDIFString());
ldifWriter.writeEntry(entry);
try
{
// Store the cookie returned with the 4rd ECL entry returned to use
// it in the test below.
cookie =
entry.getAttribute("changelogcookie").get(0).iterator().next().toString();
}
catch(NullPointerException e)
{}
}
}
assertEquals(searchOp.getSearchEntries().size(), 1);
// Now publishes a new change and search from the previous cookie
ChangeNumber cn5 = new ChangeNumber(time++, ts++, s1test.getServerId());
delMsg =
new DeleteMsg("uid="+tn+"5," + TEST_ROOT_DN_STRING, cn5, tn+"uuid5");
s1test.publish(delMsg);
sleep(500);
// Changes are :
// s1 s2
// o=test msg1,msg5 msg4
// o=test2 msg3 msg2
control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(cookie));
controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with cookie=" + cookie + "\"");
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=*"+tn+"*)"),
attributes,
controls,
null);
waitOpResult(searchOp, ResultCode.SUCCESS);
entries = searchOp.getSearchEntries();
if (entries != null)
{
for (SearchResultEntry resultEntry : entries)
{
debugInfo(tn, "Result entry=\n" + resultEntry.toLDIFString());
ldifWriter.writeEntry(resultEntry);
try
{
cookie =
resultEntry.getAttribute("changelogcookie").get(0).iterator().next().toString();
}
catch(NullPointerException e)
{}
}
}
assertEquals(searchOp.getSearchEntries().size(), 1);
cookie="";
control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(cookie));
controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with cookie=" + cookie + "\" and filter on domain=" +
"(targetDN=*direct*,o=test)");
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=*"+tn+"*,o=test)"),
attributes,
controls,
null);
waitOpResult(searchOp, ResultCode.SUCCESS);
entries = searchOp.getSearchEntries();
if (entries != null)
{
for (SearchResultEntry resultEntry : entries)
{
debugInfo(tn, "Result entry=\n" + resultEntry.toLDIFString());
ldifWriter.writeEntry(resultEntry);
try
{
cookie =
resultEntry.getAttribute("changelogcookie").get(0).iterator().next().toString();
}
catch(NullPointerException e)
{}
}
}
// we expect msg1 + msg4 + msg5
assertEquals(searchOp.getSearchEntries().size(), 3);
//
// Test startState ("first cookie") of the ECL
//
// --
ReplicationBroker s1test2 = openReplicationSession(
DN.decode(TEST_ROOT_DN_STRING2), 1203,
100, replicationServerPort,
brokerSessionTimeout, true, EMPTY_DN_GENID);
ReplicationBroker s2test = openReplicationSession(
DN.decode(TEST_ROOT_DN_STRING), 1204,
100, replicationServerPort,
brokerSessionTimeout, true);
sleep(500);
time = TimeThread.getTime();
cn = new ChangeNumber(time++, ts++, s1test2.getServerId());
delMsg =
new DeleteMsg("uid="+tn+"6," + TEST_ROOT_DN_STRING2, cn, tn+"uuid6");
s1test2.publish(delMsg);
cn = new ChangeNumber(time++, ts++, s2test.getServerId());
delMsg =
new DeleteMsg("uid="+tn+"7," + TEST_ROOT_DN_STRING, cn, tn+"uuid7");
s2test.publish(delMsg);
ChangeNumber cn8 = new ChangeNumber(time++, ts++, s1test2.getServerId());
delMsg =
new DeleteMsg("uid="+tn+"8," + TEST_ROOT_DN_STRING2, cn8, tn+"uuid8");
s1test2.publish(delMsg);
ChangeNumber cn9 = new ChangeNumber(time++, ts++, s2test.getServerId());
delMsg =
new DeleteMsg("uid="+tn+"9," + TEST_ROOT_DN_STRING, cn9, tn+"uuid9");
s2test.publish(delMsg);
sleep(500);
ReplicationServerDomain rsd =
replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING, false);
ServerState startState = rsd.getStartState();
assertTrue(startState.getMaxChangeNumber(s1test.getServerId()).getSeqnum()==1);
assertTrue(startState.getMaxChangeNumber(s2test.getServerId()) != null);
assertTrue(startState.getMaxChangeNumber(s2test.getServerId()).getSeqnum()==7);
rsd =
replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING2, false);
startState = rsd.getStartState();
assertTrue(startState.getMaxChangeNumber(s2test2.getServerId()).getSeqnum()==2);
assertTrue(startState.getMaxChangeNumber(s1test2.getServerId()).getSeqnum()==6);
//
// Test lastExternalChangelogCookie attribute of the ECL
//
MultiDomainServerState expectedLastCookie =
new MultiDomainServerState("o=test:"+cn5+" "+cn9+";o=test2:"+cn3+" "+cn8+";");
String lastCookie = readLastCookie(tn);
assertTrue(expectedLastCookie.equalsTo(new MultiDomainServerState(lastCookie)),
" Expected last cookie attribute value:" + expectedLastCookie +
" Read from server: " + lastCookie + " are equal :");
// Test invalid cookie
cookie += ";o=test6:";
control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(cookie));
controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with bad domain in cookie=" + cookie);
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=*"+tn+"*,o=test)"),
attributes,
controls,
null);
waitOpResult(searchOp, ResultCode.UNWILLING_TO_PERFORM);
assertEquals(searchOp.getSearchEntries().size(), 0);
assertTrue(searchOp.getErrorMessage().toString().equals(
ERR_INVALID_COOKIE_SYNTAX.get().toString()),
searchOp.getErrorMessage().toString());
// Test unknown domain in provided cookie
// This case seems to be very hard to obtain in the real life
// (how to remove a domain from a RS topology ?)
// let's do a very quick test here.
String newCookie = lastCookie + "o=test6:";
control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(newCookie));
controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with bad domain in cookie=" + cookie);
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=*"+tn+"*,o=test)"),
attributes,
controls,
null);
waitOpResult(searchOp, ResultCode.UNWILLING_TO_PERFORM);
assertEquals(searchOp.getSearchEntries().size(), 0);
assertTrue(searchOp.getErrorMessage().toString().startsWith(
ERR_RESYNC_REQUIRED_UNKNOWN_DOMAIN_IN_PROVIDED_COOKIE.get("{o=test6=}").toString().replace(")","")),
searchOp.getErrorMessage().toString());
// The cookie value is not tested because it is build from a hashmap in
// the server and the order of domains is not predictable.
// Test missing domain in provided cookie
newCookie = lastCookie.substring(lastCookie.indexOf(';')+1);
control =
new ExternalChangelogRequestControl(true,
new MultiDomainServerState(newCookie));
controls = new ArrayList<Control>(0);
controls.add(control);
debugInfo(tn, "Search with bad domain in cookie=" + cookie);
searchOp = connection.processSearch(
ByteString.valueOf("cn=changelog"),