| | |
| | | { |
| | | replayOperations.remove(replayOperations.firstKey()); |
| | | } |
| | | replayOperations.put( |
| | | csn, |
| | | new FakeDelOperation( |
| | | deleteOperation.getEntryDN().toString(), |
| | | csn, modifiedEntryUUID)); |
| | | FakeOperation op = new FakeDelOperation( |
| | | deleteOperation.getEntryDN(), csn, modifiedEntryUUID); |
| | | replayOperations.put(csn, op); |
| | | } |
| | | |
| | | } |
| | |
| | | { |
| | | // There is an entry with the same unique id as this modify operation |
| | | // replay the modify using the current dn of this entry. |
| | | msg.setDn(newDN.toString()); |
| | | msg.setDN(newDN); |
| | | numResolvedNamingConflicts.incrementAndGet(); |
| | | return false; |
| | | } |
| | |
| | | /* |
| | | * Find if the entry is still in the database. |
| | | */ |
| | | DN currentDn = findEntryDN(entryUUID); |
| | | if (currentDn == null) |
| | | DN currentDN = findEntryDN(entryUUID); |
| | | if (currentDN == null) |
| | | { |
| | | /* |
| | | * The entry has already been deleted, either because this delete |
| | |
| | | } |
| | | else |
| | | { |
| | | /* |
| | | * This entry has been renamed, replay the delete using its new DN. |
| | | */ |
| | | msg.setDn(currentDn.toString()); |
| | | // This entry has been renamed, replay the delete using its new DN. |
| | | msg.setDN(currentDN); |
| | | numResolvedNamingConflicts.incrementAndGet(); |
| | | return false; |
| | | } |
| | |
| | | * The action taken here must be consistent with the actions |
| | | * done in the solveNamingConflict(AddOperation) method |
| | | * when we are adding an entry whose parent entry has already been deleted. |
| | | * |
| | | */ |
| | | if (findAndRenameChild(op.getEntryDN(), op)) |
| | | { |
| | |
| | | * reconstruct the operation with the DN we just built |
| | | */ |
| | | ModifyDNMsg modifyDnMsg = (ModifyDNMsg) msg; |
| | | msg.setDn(currentDN.toString()); |
| | | modifyDnMsg.setDN(currentDN); |
| | | modifyDnMsg.setNewSuperior(newSuperior.toString()); |
| | | numResolvedNamingConflicts.incrementAndGet(); |
| | | return false; |
| | |
| | | */ |
| | | addConflict(msg); |
| | | |
| | | msg.setDn(generateConflictRDN(entryUUID, |
| | | op.getEntryDN().getRDN().toString()) + "," + getBaseDNString()); |
| | | String conflictRDN = |
| | | generateConflictRDN(entryUUID, op.getEntryDN().getRDN().toString()); |
| | | msg.setDN(DN.decode(conflictRDN + "," + getBaseDNString())); |
| | | // reset the parent entryUUID so that the check done is the |
| | | // handleConflict phase does not fail. |
| | | msg.setParentEntryUUID(null); |
| | |
| | | } |
| | | else |
| | | { |
| | | RDN entryRdn = DN.decode(msg.getDn()).getRDN(); |
| | | msg.setDn(entryRdn + "," + parentDn); |
| | | msg.setDN(DN.decode(msg.getDN().getRDN() + "," + parentDn)); |
| | | numResolvedNamingConflicts.incrementAndGet(); |
| | | } |
| | | return false; |
| | |
| | | else |
| | | { |
| | | addConflict(msg); |
| | | msg.setDn(generateConflictRDN(entryUUID, msg.getDn())); |
| | | String conflictRDN = |
| | | generateConflictRDN(entryUUID, msg.getDN().toNormalizedString()); |
| | | msg.setDN(DN.decode(conflictRDN)); |
| | | numUnresolvedNamingConflicts.incrementAndGet(); |
| | | return false; |
| | | } |
| | |
| | | |
| | | /** |
| | | * Find all the entries below the provided DN and rename them |
| | | * so that they stay below the baseDn of this replicationDomain and |
| | | * so that they stay below the baseDN of this replicationDomain and |
| | | * use the conflicting name and attribute. |
| | | * |
| | | * @param entryDN The DN of the entry whose child must be renamed. |
| | |
| | | |
| | | /** |
| | | * Rename an entry that was conflicting so that it stays below the |
| | | * baseDn of the replicationDomain. |
| | | * baseDN of the replicationDomain. |
| | | * |
| | | * @param conflictOp The Operation that caused the conflict. |
| | | * @param dn The DN of the entry to be renamed. |
| | |
| | | */ |
| | | private void addConflict(AddMsg msg) throws ASN1Exception |
| | | { |
| | | String normalizedDN; |
| | | try |
| | | { |
| | | normalizedDN = DN.decode(msg.getDn()).toNormalizedString(); |
| | | } catch (DirectoryException e) |
| | | { |
| | | normalizedDN = msg.getDn(); |
| | | } |
| | | String normalizedDN = msg.getDN().toNormalizedString(); |
| | | |
| | | // Generate an alert to let the administrator know that some |
| | | // conflict could not be solved. |
| | |
| | | os = output; |
| | | } |
| | | |
| | | // baseDn branch is the only one included in the export |
| | | // baseDN branch is the only one included in the export |
| | | List<DN> includeBranches = new ArrayList<DN>(1); |
| | | includeBranches.add(getBaseDN()); |
| | | LDIFExportConfig exportConfig = new LDIFExportConfig(os); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Retrieves a replication domain based on the baseDn. |
| | | * Retrieves a replication domain based on the baseDN. |
| | | * |
| | | * @param baseDn The baseDn of the domain to retrieve |
| | | * @param baseDN The baseDN of the domain to retrieve |
| | | * @return The domain retrieved |
| | | * @throws DirectoryException When an error occurred or no domain |
| | | * match the provided baseDn. |
| | | * match the provided baseDN. |
| | | */ |
| | | public static LDAPReplicationDomain retrievesReplicationDomain(DN baseDn) |
| | | throws DirectoryException |
| | | public static LDAPReplicationDomain retrievesReplicationDomain(DN baseDN) |
| | | throws DirectoryException |
| | | { |
| | | LDAPReplicationDomain replicationDomain = null; |
| | | |
| | |
| | | |
| | | // From the domainDN retrieves the replication domain |
| | | LDAPReplicationDomain domain = |
| | | MultimasterReplication.findDomain(baseDn, null); |
| | | MultimasterReplication.findDomain(baseDN, null); |
| | | if (domain == null) |
| | | { |
| | | break; |
| | |
| | | if (replicationDomain == null) |
| | | { |
| | | throw new DirectoryException(ResultCode.OTHER, |
| | | ERR_NO_MATCHING_DOMAIN.get(String.valueOf(baseDn))); |
| | | ERR_NO_MATCHING_DOMAIN.get(String.valueOf(baseDN))); |
| | | } |
| | | return replicationDomain; |
| | | } |
| | |
| | | * attribute. The only changes that will be send will be the one generated on |
| | | * the serverId provided in fromCSN. |
| | | * |
| | | * @param baseDn |
| | | * @param baseDN |
| | | * the base DN |
| | | * @param fromCSN |
| | | * The CSN from which we want the changes |
| | |
| | | * @throws Exception |
| | | * when raised. |
| | | */ |
| | | private static InternalSearchOperation searchForChangedEntries(DN baseDn, |
| | | private static InternalSearchOperation searchForChangedEntries(DN baseDN, |
| | | CSN fromCSN, CSN lastCSN, InternalSearchListener resultListener) |
| | | throws Exception |
| | | { |
| | |
| | | "(" + HISTORICAL_ATTRIBUTE_NAME + "<=dummy:" + maxValueForId + "))"); |
| | | |
| | | return conn.processSearch( |
| | | ByteString.valueOf(baseDn.toString()), |
| | | ByteString.valueOf(baseDN.toString()), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, |
| | | 0, 0, false, filter, |
| | |
| | | * attribute. The only changes that will be send will be the one generated on |
| | | * the serverId provided in fromCSN. |
| | | * |
| | | * @param baseDn |
| | | * @param baseDN |
| | | * the base DN |
| | | * @param fromCSN |
| | | * The CSN from which we want the changes |
| | |
| | | * @throws Exception |
| | | * when raised. |
| | | */ |
| | | public static InternalSearchOperation searchForChangedEntries(DN baseDn, |
| | | public static InternalSearchOperation searchForChangedEntries(DN baseDN, |
| | | CSN fromCSN, InternalSearchListener resultListener) throws Exception |
| | | { |
| | | return searchForChangedEntries(baseDn, fromCSN, null, resultListener); |
| | | return searchForChangedEntries(baseDN, fromCSN, null, resultListener); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * Base DN the fractional configuration is for. |
| | | */ |
| | | private DN baseDn; |
| | | private DN baseDN; |
| | | |
| | | /** |
| | | * Constructs a new fractional configuration object. |
| | | * @param baseDn The base dn the object is for. |
| | | * @param baseDN The base DN the object is for. |
| | | */ |
| | | FractionalConfig(DN baseDn) |
| | | FractionalConfig(DN baseDN) |
| | | { |
| | | this.baseDn = baseDn; |
| | | this.baseDN = baseDN; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * Getter for the base baseDn. |
| | | * @return The baseDn attribute. |
| | | * Getter for the base baseDN. |
| | | * @return The baseDN attribute. |
| | | */ |
| | | DN getBaseDn() |
| | | { |
| | | return baseDn; |
| | | return baseDN; |
| | | } |
| | | |
| | | /** |