*
* To simulate this try to rename an entry below an entry that does
* not exist but giving the unique ID of an existing entry.
*/
ModifyDNMsg modDnMsg = new ModifyDNMsg(
"uid=new person,ou=People," + TEST_ROOT_DN_STRING, gen.newChangeNumber(),
user1entryUUID, baseUUID, false,
"uid=wrong, ou=people," + TEST_ROOT_DN_STRING,
"uid=newrdn");
updateMonitorCount(baseDn, resolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
broker.publish(modDnMsg);
resultEntry = getEntry(
DN.decode("uid=newrdn,ou=People," + TEST_ROOT_DN_STRING), 10000, true);
// check that the operation has been correctly relayed
assertNotNull(resultEntry,
"The modify dn was not or badly replayed");
assertEquals(getMonitorDelta(), 1);
// Check that there was no administrative alert generated
// because the conflict has been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount,
"An alert was incorrectly generated when resolving conflicts");
/*
* same test but by giving a bad entry DN
*/
modDnMsg = new ModifyDNMsg(
"uid=wrong,ou=People," + TEST_ROOT_DN_STRING, gen.newChangeNumber(),
user1entryUUID, null, false, null, "uid=reallynewrdn");
updateMonitorCount(baseDn, resolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
broker.publish(modDnMsg);
resultEntry = getEntry(
DN.decode("uid=reallynewrdn,ou=People," + TEST_ROOT_DN_STRING), 10000, true);
// check that the operation has been correctly relayed
assertNotNull(resultEntry,
"The modify dn was not or badly replayed");
assertEquals(getMonitorDelta(), 1);
// Check that there was no administrative alert generated
// because the conflict has been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount,
"An alert was incorrectly generated when resolving conflicts");
/*
* Check that conflicting entries are renamed when a
* modifyDN is done with the same DN as an entry added on another server.
*/
// add a second entry
addMsg = new AddMsg(gen.newChangeNumber(),
user1dn,
user1entrysecondUUID,
baseUUID,
personWithSecondUniqueID.getObjectClassAttribute(),
personWithSecondUniqueID.getAttributes(), new ArrayList<Attribute>());
broker.publish(addMsg);
// check that the second entry has been added
resultEntry = getEntry(DN.decode(user1dn), 10000, true);
// check that the add operation has been applied
assertNotNull(resultEntry, "The add operation was not replayed");
// try to rename the first entry
modDnMsg = new ModifyDNMsg(user1dn, gen.newChangeNumber(),
user1entrysecondUUID, baseUUID, false,
baseDn.toString(), "uid=reallynewrdn");
updateMonitorCount(baseDn, unresolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
broker.publish(modDnMsg);
// check that the second entry has been renamed
resultEntry = getEntry(
DN.decode("entryUUID = " + user1entrysecondUUID + "+uid=reallynewrdn," +
"ou=People," + TEST_ROOT_DN_STRING), 10000, true);
assertNotNull(resultEntry, "The modifyDN was not or incorrectly replayed");
assertEquals(getMonitorDelta(), 1);
assertConflictAttribute(resultEntry);
// Check that there was no administrative alert generated
// because the conflict has been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount+1,
"An alert was not generated when resolving conflicts");
// delete the entries to clean the database
delMsg =
new DeleteMsg("entryUUID = " + user1entrysecondUUID + "+" +
DN.decode(user1dn).getRDN().toString() +
",ou=People," + TEST_ROOT_DN_STRING,
gen.newChangeNumber(), user1entrysecondUUID);
broker.publish(delMsg);
resultEntry = getEntry(
DN.decode("entryUUID = " + user1entrysecondUUID + "+" +
DN.decode(user1dn).getRDN().toString() +
",ou=People," + TEST_ROOT_DN_STRING), 10000, false);
// check that the delete operation has been applied
assertNull(resultEntry,
"The DELETE replication message was not replayed");
delMsg =
new DeleteMsg("uid=reallynewrdn,ou=People," + TEST_ROOT_DN_STRING,
gen.newChangeNumber(), user1entryUUID);
broker.publish(delMsg);
resultEntry = getEntry(
DN.decode("uid=reallynewrdn,ou=People," + TEST_ROOT_DN_STRING), 10000, false);
// check that the delete operation has been applied
assertNull(resultEntry,
"The DELETE replication message was not replayed");
/*
* When replaying add operations it is possible that the parent entry has
* been renamed before and that another entry have taken the former dn of
* the parent entry. In such case the replication replay code should
* detect that the parent has been renamed and should add the entry below
* the new dn of the parent (thus changing the original dn with which the
* entry had been created)
*
* Steps
* - create parent entry 1 with baseDn1
* - create Add Msg for user1 with parent entry 1 UUID
* - MODDN parent entry 1 to baseDn2 in the LDAP server
* - add new parent entry 2 with baseDn1
* - publish msg
* - check that the Dn has been changed to baseDn2 in the msg received
*/
// - create parent entry 1 with baseDn1
String[] topEntries = new String[1];
topEntries[0] = "dn: ou=baseDn1,"+baseDn+"\n" + "objectClass: top\n"
+ "objectClass: organizationalUnit\n"
+ "entryUUID: 55555555-5555-5555-5555-555555555555\n";
Entry entry;
for (String entryStr : topEntries)
{
entry = TestCaseUtils.entryFromLdifString(entryStr);
AddOperationBasis addOp = new AddOperationBasis(connection,
InternalClientConnection.nextOperationID(), InternalClientConnection
.nextMessageID(), null, entry.getDN(), entry.getObjectClasses(),
entry.getUserAttributes(), entry.getOperationalAttributes());
addOp.setInternalOperation(true);
addOp.run();
}
resultEntry = getEntry(
DN.decode("ou=baseDn1,"+baseDn), 10000, true);
assertNotNull(resultEntry,
"Entry not added: ou=baseDn1,"+baseDn);
// - create Add Msg for user1 with parent entry 1 UUID
addMsg = new AddMsg(gen.newChangeNumber(),
"uid=new person,ou=baseDn1,"+baseDn,
user1entryUUID,
getEntryUUID(DN.decode("ou=baseDn1,"+baseDn)),
personWithUUIDEntry.getObjectClassAttribute(),
personWithUUIDEntry.getAttributes(), new ArrayList<Attribute>());
// - MODDN parent entry 1 to baseDn2 in the LDAP server
ModifyDNOperationBasis modDNOp = new ModifyDNOperationBasis(connection,
InternalClientConnection.nextOperationID(), InternalClientConnection
.nextMessageID(), null,
DN.decode("ou=baseDn1,"+baseDn),
RDN.decode("ou=baseDn2"), true,
baseDn);
modDNOp.run();
resultEntry = getEntry(
DN.decode("ou=baseDn2,"+baseDn), 10000, true);
assertNotNull(resultEntry,
"Entry not moved from ou=baseDn1,"+baseDn+" to ou=baseDn2,"+baseDn);
// - add new parent entry 2 with baseDn1
String p2 = "dn: ou=baseDn1,"+baseDn+"\n" + "objectClass: top\n"
+ "objectClass: organizationalUnit\n"
+ "entryUUID: 66666666-6666-6666-6666-666666666666\n";
entry = TestCaseUtils.entryFromLdifString(p2);
AddOperationBasis addOp = new AddOperationBasis(connection,
InternalClientConnection.nextOperationID(), InternalClientConnection
.nextMessageID(), null, entry.getDN(), entry.getObjectClasses(),
entry.getUserAttributes(), entry.getOperationalAttributes());
addOp.setInternalOperation(true);
addOp.run();
// - publish msg
updateMonitorCount(baseDn, resolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
broker.publish(addMsg);
// - check that the DN has been changed to baseDn2
resultEntry = getEntry(
DN.decode("uid=new person,ou=baseDn1,"+baseDn), 10000, false);
assertNull(resultEntry,
"The ADD replication message was applied under ou=baseDn1,"+baseDn);
resultEntry = getEntry(
DN.decode("uid=new person,ou=baseDn2,"+baseDn), 10000, true);
assertNotNull(resultEntry,
"The ADD replication message was NOT applied under ou=baseDn2,"+baseDn);
assertEquals(getMonitorDelta(), 1);
// Check that there was no administrative alert generated
// because the conflict has been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount,
"An alert was incorrectly generated when resolving conflicts");
//
// Check that when a delete is conflicting with Add of some entries
// below the deleted entries, the child entry that have been added
// before the deleted is replayed gets renamed correctly.
//
// add domain1 entry with 2 children : domain2 and domain3
addEntry(domain1);
ChangeNumber olderCn = gen.newChangeNumber();
Thread.sleep(1000);
domain1uid = getEntryUUID(DN.decode(domain1dn));
addEntry(domain2);
domain2uid = getEntryUUID(DN.decode(domain2dn));
addEntry(domain3);
domain3uid = getEntryUUID(DN.decode(domain3dn));
DN conflictDomain2dn = DN.decode(
"entryUUID = " + domain2uid + "+dc=domain2,ou=people," + TEST_ROOT_DN_STRING);
DN conflictDomain3dn = DN.decode(
"entryUUID = " + domain3uid + "+dc=domain3,ou=people," + TEST_ROOT_DN_STRING);
updateMonitorCount(baseDn, unresolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
// delete domain1
delMsg = new DeleteMsg(domain1dn, olderCn, domain1uid);
broker.publish(delMsg);
// check that the domain1 has correctly been deleted
assertNull(getEntry(DN.decode(domain1dn), 10000, false),
"The DELETE replication message was not replayed");
// check that domain2 and domain3 have been renamed
assertNotNull(getEntry(conflictDomain2dn, 1000, true),
"The conflicting entries were not created");
assertNotNull(getEntry(conflictDomain3dn, 1000, true),
"The conflicting entries were not created");
// check that the 2 conflicting entries have been correctly marked
assertTrue(checkEntryHasAttribute(conflictDomain2dn,
LDAPReplicationDomain.DS_SYNC_CONFLICT, domain2dn, 1000, true));
assertTrue(checkEntryHasAttribute(conflictDomain3dn,
LDAPReplicationDomain.DS_SYNC_CONFLICT, domain3dn, 1000, true));
// check that unresolved conflict count has been incremented
assertEquals(getMonitorDelta(), 1);
// Check that an administrative alert was generated
// because the conflict has not been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount+2,
"An alert was incorrectly generated when resolving conflicts");
// delete the resulting entries for the next test
delEntry(conflictDomain2dn);
delEntry(conflictDomain3dn);
//
// Check that when a delete is replayed over an entry which has child
// those child are also deleted
//
// add domain1 entry with 2 children : domain2 and domain3
addEntry(domain1);
domain1uid = getEntryUUID(DN.decode(domain1dn));
addEntry(domain2);
domain2uid = getEntryUUID(DN.decode(domain2dn));
ChangeNumber addCn = addEntry(domain3);
gen.adjust(addCn);
domain3uid = getEntryUUID(DN.decode(domain3dn));
updateMonitorCount(baseDn, unresolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
// delete domain1
delMsg = new DeleteMsg(domain1dn, gen.newChangeNumber(), domain1uid);
broker.publish(delMsg);
// check that the domain1 has correctly been deleted
assertNull(getEntry(DN.decode(domain1dn), 10000, false),
"The DELETE replication message was not replayed");
// check that domain2 and domain3 have been renamed as conflicting
String confDomain2dn = "entryuuid="+domain2uid+"+dc=domain2,ou=people,"+TEST_ROOT_DN_STRING;
String confDomain3dn = "entryuuid="+domain3uid+"+dc=domain3,ou=people,"+TEST_ROOT_DN_STRING;
assertTrue(DirectoryServer.entryExists(DN.decode(confDomain2dn)),
"The conflicting entry exist for domain2" + confDomain2dn);
assertTrue(DirectoryServer.entryExists(DN.decode(confDomain3dn)),
"The conflicting entry exist for domain3" + confDomain3dn);
// check that unresolved conflict count has been incremented
assertEquals(getMonitorDelta(), 1);
delEntry(DN.decode(confDomain2dn));
delEntry(DN.decode(confDomain3dn));
//
// Check that when an entry is added on one master below an entry
// that is currently deleted on another master, the replay of the
// add on the second master cause the added entry to be renamed
//
addMsg = new AddMsg(gen.newChangeNumber(), domain2dn, domain2uid,
domain1uid,
domain2.getObjectClassAttribute(),
domain2.getAttributes(), new ArrayList<Attribute>());
broker.publish(addMsg);
// check that conflict entry was created
assertNotNull(getEntry(conflictDomain2dn, 1000, true),
"The conflicting entries were not created");
// check that the entry have been correctly marked as conflicting.
assertTrue(checkEntryHasAttribute(conflictDomain2dn,
LDAPReplicationDomain.DS_SYNC_CONFLICT, domain2dn, 1000, true));
// check that unresolved conflict count has been incremented
assertEquals(getMonitorDelta(), 1);
// Check that when an entry is deleted on a first master and
// renamed on a second master and the rename is replayed last
// this is correctly detected as a resolved conflict.
// To simulate this simply try a modifyDN on a non existent uid.
modDnMsg = new ModifyDNMsg(
"uid=new person,ou=People," + TEST_ROOT_DN_STRING, gen.newChangeNumber(),
"33343333-3533-3633-3373-333333833333", baseUUID, false,
"uid=wrong, ou=people," + TEST_ROOT_DN_STRING,
"uid=newrdn");
updateMonitorCount(baseDn, resolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
broker.publish(modDnMsg);
// unfortunately it is difficult to check that the operation
// did not do anything.
// The only thing we can check is that resolved naming conflict counter
// has correctly been incremented.
int count = 0;
while ((count<2000) && getMonitorDelta() == 0)
{
// it is possible that the update has not yet been applied
// wait a short time and try again.
Thread.sleep(100);
count++;
}
// if the monitor counter did not get incremented after 200sec
// then something got wrong.
assertTrue(count < 200);
// Check that there was no administrative alert generated
// because the conflict has been automatically resolved.
assertEquals(DummyAlertHandler.getAlertCount(), AlertCount,
"An alert was incorrectly generated when resolving conflicts");
/*
* Check that a conflict is detected when an entry is
* moved below an entry that does not exist.
*/
updateMonitorCount(baseDn, unresolvedMonitorAttr);
AlertCount = DummyAlertHandler.getAlertCount();
modDnMsg = new ModifyDNMsg(
"uid=new person,ou=People," + TEST_ROOT_DN_STRING, gen.newChangeNumber(),
"33333333-3333-3333-3333-333333333333",
"12343333-3533-3633-3333-333333833333" , false,
"uid=wrong, ou=people," + TEST_ROOT_DN_STRING,
"uid=newrdn");