*/
private boolean solveNamingConflict(AddOperation op,
AddMsg msg) throws Exception
{
ResultCode result = op.getResultCode();
AddContext ctx = (AddContext) op.getAttachment(SYNCHROCONTEXT);
String entryUid = ctx.getEntryUid();
String parentUniqueId = ctx.getParentUid();
if (result == ResultCode.NO_SUCH_OBJECT)
{
/*
* This can happen if the parent has been renamed or deleted
* find the parent dn and calculate a new dn for the entry
*/
if (parentUniqueId == null)
{
/*
* This entry is the base dn of the backend.
* It is quite surprising that the operation result be NO_SUCH_OBJECT.
* There is nothing more we can do except TODO log a
* message for the repair tool to look at this problem.
*/
return true;
}
DN parentDn = findEntryDN(parentUniqueId);
if (parentDn == null)
{
/*
* The parent has been deleted
* rename the entry as a conflicting entry.
* The action taken here must be consistent with the actions
* done when in the solveNamingConflict(DeleteOperation) method
* when we are deleting an entry that have some child entries.
*/
addConflict(msg);
msg.setDn(generateConflictRDN(entryUid,
op.getEntryDN().getRDN().toString()) + ","
+ baseDn);
// reset the parent uid so that the check done is the handleConflict
// phase does not fail.
msg.setParentUid(null);
numUnresolvedNamingConflicts.incrementAndGet();
return false;
}
else
{
RDN entryRdn = DN.decode(msg.getDn()).getRDN();
msg.setDn(entryRdn + "," + parentDn);
numResolvedNamingConflicts.incrementAndGet();
return false;
}
}
else if (result == ResultCode.ENTRY_ALREADY_EXISTS)
{
/*
* This can happen if
* - two adds are done on different servers but with the
* same target DN.
* - the same ADD is being replayed for the second time on this server.
* if the nsunique ID already exist, assume this is a replay and
* don't do anything
* if the entry unique id do not exist, generate conflict.
*/
if (findEntryDN(entryUid) != null)
{
// entry already exist : this is a replay
return true;
}
else
{
addConflict(msg);
msg.setDn(generateConflictRDN(entryUid, msg.getDn()));
numUnresolvedNamingConflicts.incrementAndGet();
return false;
}
}
else
{
// The other type of errors can not be caused by naming conflicts.
// log a message for the repair tool.
Message message = ERR_ERROR_REPLAYING_OPERATION.get(
op.toString(), ctx.getChangeNumber().toString(),
result.toString(), op.getErrorMessage().toString());
logError(message);
return true;
}
}