| | |
| | | ds-cfg-rotation-policy-dn: cn=Size Limit Rotation Policy,cn=Log Rotation Policies,cn=config |
| | | ds-cfg-retention-policy-dn: cn=File Count Retention Policy,cn=Log Retention Policies,cn=config |
| | | |
| | | dn: cn=Replication Repair Logger,cn=Loggers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-logger |
| | | objectClass: ds-cfg-error-logger |
| | | objectClass: ds-cfg-file-based-error-logger |
| | | cn: File-Based Error Logger |
| | | ds-cfg-logger-class: org.opends.server.loggers.TextErrorLogPublisher |
| | | ds-cfg-logger-enabled: true |
| | | ds-cfg-log-file: logs/replication |
| | | ds-cfg-log-file-mode: 640 |
| | | ds-cfg-default-severity: none |
| | | ds-cfg-override-severity: SYNC=INFO,MILD_ERROR,MILD_WARNING,NOTICE |
| | | ds-cfg-asynchronous-writes: false |
| | | ds-cfg-rotation-policy-dn: cn=7 Days Time Limit Rotation Policy,cn=Log Rotation Policies,cn=config |
| | | ds-cfg-rotation-policy-dn: cn=Size Limit Rotation Policy,cn=Log Rotation Policies,cn=config |
| | | ds-cfg-retention-policy-dn: cn=File Count Retention Policy,cn=Log Retention Policies,cn=config |
| | | |
| | | dn: cn=File-Based Debug Logger,cn=Loggers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-logger |
| | |
| | | ds-cfg-num-worker-threads: 24 |
| | | ds-cfg-max-work-queue-capacity: 0 |
| | | |
| | | dn: cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-synchronization-provider |
| | | objectClass: ds-cfg-multimaster-synchronization-provider |
| | | cn: Multimaster Synchronization |
| | | ds-cfg-synchronization-provider-enabled: true |
| | | ds-cfg-synchronization-provider-class: org.opends.server.replication.plugin.MultimasterReplication |
| | | |
| | | dn: cn=domains,cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-branch |
| | | cn: domains |
| | |
| | | # cn=Replication Server, cn=Multimaster Synchronization, cn=Synchronization Providers, cn=config |
| | | # entry. |
| | | |
| | | |
| | | dn: cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-synchronization-provider |
| | | objectClass: ds-cfg-multimaster-synchronization-provider |
| | | cn: Multimaster Synchronization |
| | | ds-cfg-synchronization-provider-enabled: true |
| | | ds-cfg-synchronization-provider-class: org.opends.server.replication.plugin.MultimasterReplication |
| | | |
| | | dn: cn=domains,cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-branch |
| | | cn: domains |
| | | |
| | | dn: cn=example,cn=domains,cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-replication-domain-config |
| | |
| | | Messages of all severity levels will be logged. |
| | | </adm:synopsis> |
| | | </adm:value> |
| | | <adm:value name="none"> |
| | | <adm:synopsis> |
| | | No messages of any severity will be logged by default. |
| | | This value is intended to be used in conjunction with |
| | | the override-severity property to define an error |
| | | logger that will publish no error message beside the errors |
| | | of a given category. |
| | | </adm:synopsis> |
| | | </adm:value> |
| | | <adm:value name="fatal-error"> |
| | | <adm:synopsis> |
| | | The error log severity that will be used for messages that |
| | |
| | | # CDDL HEADER END |
| | | # |
| | | # Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | |
| | | # |
| | | # |
| | | # This file contains the primary Directory Server configuration. It must not |
| | | # be directly edited while the server is online. The server configuration |
| | | # should only be managed using the administration utilities provided with the |
| | | # Directory Server. |
| | | |
| | | |
| | | # |
| | |
| | | MILD_ERR_COULD_NOT_BIND_CHANGELOG_6=Changelog failed to start : could not \ |
| | | bind to the changelog listen port : %d. Error : %s |
| | | MILD_ERR_UNKNOWN_TYPE_7=Unknown operation type : %s |
| | | MILD_ERR_ERROR_REPLAYING_OPERATION_8=Error %s when replaying operation with \ |
| | | changenumber %s %s : %s |
| | | MILD_ERR_OPERATION_NOT_FOUND_IN_PENDING_9=Internal Error : Operation %s \ |
| | | change number %s was not found in pending list |
| | | MILD_ERR_COULD_NOT_INITIALIZE_DB_10=Changelog failed to start because the \ |
| | |
| | | MILD_ERR_EXCEPTION_REPLAYING_OPERATION_12=An Exception was caught while \ |
| | | replaying operation %s : %s |
| | | MILD_ERR_NEED_CHANGELOG_PORT_13=The replication server port must be defined |
| | | MILD_ERR_ERROR_UPDATING_RUV_14=Error %s when updating server state %s : %s \ |
| | | DEBUG_ERROR_UPDATING_RUV_14=Error %s when updating server state %s : %s \ |
| | | base dn : %s |
| | | MILD_ERR_ERROR_SEARCHING_RUV_15=Error %s when searching for server state %s : \ |
| | | %s base dn : %s |
| | |
| | | server should be configured |
| | | NOTICE_EXCEPTION_STARTING_SESSION_20=Caught Exception during initial \ |
| | | communication with replication server : |
| | | NOTICE_CANNOT_RECOVER_CHANGES_21=Error when searching old changes from the \ |
| | | database |
| | | MILD_ERR_CANNOT_RECOVER_CHANGES_21=Error when searching old changes from the \ |
| | | database for base DN %s |
| | | NOTICE_COULD_NOT_FIND_CHANGELOG_WITH_MY_CHANGES_22=Could not find a \ |
| | | replication server that has seen all the local changes. Going to replay \ |
| | | changes |
| | |
| | | SEVERE_ERR_EXCEPTION_RECEIVING_REPLICATION_MESSAGE_34=An Exception was caught \ |
| | | while receiving replication message : %s |
| | | MILD_ERR_LOOP_REPLAYING_OPERATION_35=A loop was detected while replaying \ |
| | | operation: %s |
| | | operation: %s error %s |
| | | MILD_ERR_FILE_CHECK_CREATE_FAILED_36=An Exception was caught while testing \ |
| | | existence or trying to create the directory for the changelog database : %s |
| | | INFO_CHANGELOG_SERVER_ATTR_37=Specifies the list of replication servers to \ |
| | |
| | | have the same ServerId : %d |
| | | SEVERE_ERR_BAD_HISTORICAL_56=Entry %s was containing some unknown historical \ |
| | | information, This may cause some inconsistency for this entry |
| | | SEVERE_ERR_CANNOT_ADD_CONFLICT_ATTRIBUTE_57=A conflict was detected but the \ |
| | | MILD_ERR_CANNOT_ADD_CONFLICT_ATTRIBUTE_57=A conflict was detected but the \ |
| | | conflict information could not be added. Operation : |
| | | SEVERE_ERR_CANNOT_RENAME_CONFLICT_ENTRY_58=An error happened trying the \ |
| | | MILD_ERR_CANNOT_RENAME_CONFLICT_ENTRY_58=An error happened trying to \ |
| | | rename a conflicting entry : |
| | | SEVERE_ERR_EXCEPTION_RENAME_CONFLICT_ENTRY_59=An Exception happened when \ |
| | | trying the rename a conflicting entry : |
| | | MILD_ERR_EXCEPTION_RENAME_CONFLICT_ENTRY_59=An Exception happened when \ |
| | | trying to rename a conflicting entry : |
| | | SEVERE_ERR_CHANGELOG_UNSUPPORTED_UTF8_ENCODING_60=The JVM does not support \ |
| | | UTF-8. This is required to be able to encode the changes in the database. \ |
| | | This replication server will now shutdown |
| | |
| | | and reopened |
| | | SEVERE_ERR_CHANGELOG_ERROR_SENDING_MSG_66=An unexpected error occurred while \ |
| | | sending a Message to %s. This connection is going to be closed and reopened |
| | | MILD_ERR_ERROR_REPLAYING_OPERATION_67=Could not replay operation %s with \ |
| | | ChangeNumber %s error %s %s |
| | | MILD_ERR_UNKNOWN_ATTRIBUTE_IN_HISTORICAL_68=The entry %s has historical \ |
| | | information for attribute %s which is not defined in the schema. This \ |
| | | information will be ignored |
| | |
| | | defaultSeverities.add(Severity.SEVERE_ERROR); |
| | | defaultSeverities.add(Severity.SEVERE_WARNING); |
| | | } |
| | | else if (defSev.toString().equalsIgnoreCase(LOG_SEVERITY_NONE)) |
| | | { |
| | | // don't add any severity |
| | | } |
| | | else |
| | | { |
| | | Severity errorSeverity = |
| | |
| | | defaultSeverities.add(Severity.SEVERE_ERROR); |
| | | defaultSeverities.add(Severity.SEVERE_WARNING); |
| | | } |
| | | else if (defSev.toString().equalsIgnoreCase(LOG_SEVERITY_NONE)) |
| | | { |
| | | // don't add any severity |
| | | } |
| | | else |
| | | { |
| | | Severity errorSeverity = |
| | |
| | | * |
| | | * @param mod A modification that must be adde to the list of modifications |
| | | * included in this fake operation. |
| | | * @throws Exception when the addition of this type of modification |
| | | * is not valid for this FakeOperation. |
| | | */ |
| | | abstract public void addModification(Modification mod) throws Exception; |
| | | abstract public void addModification(Modification mod); |
| | | |
| | | } |
| | |
| | | * This attribute is unknown from the schema |
| | | * Just skip it, the modification will be processed but no |
| | | * historical information is going to be kept. |
| | | * TODO : REPAIR tool should deal with this, add some logging. |
| | | * Log information for the repair tool. |
| | | */ |
| | | Message message = ERR_UNKNOWN_ATTRIBUTE_IN_HISTORICAL.get( |
| | | entry.getDN().toNormalizedString(), histVal.getAttrString()); |
| | | logError(message); |
| | | continue; |
| | | } |
| | | |
| | |
| | | |
| | | if (fakeOperation != null) |
| | | { |
| | | try |
| | | { |
| | | fakeOperation.addModification(mod); |
| | | } catch (Exception e) |
| | | { |
| | | /* |
| | | * TODO : REPAIR : This Exception shows that there are some |
| | | * inconsistency in the historical information. |
| | | * This method can't fix the problem. |
| | | * This should be logged and somehow the repair |
| | | * service should get called to fix the problem. |
| | | */ |
| | | } |
| | | fakeOperation.addModification(mod); |
| | | } |
| | | else |
| | | { |
| | |
| | | |
| | | import org.opends.server.types.BackupConfig; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Entry; |
| | |
| | | import org.opends.server.types.operation.PreOperationModifyOperation; |
| | | import org.opends.messages.Message; |
| | | |
| | | import static org.opends.server.replication.plugin. |
| | | ReplicationRepairRequestControl.*; |
| | | |
| | | /** |
| | | * This class is used to load the Replication code inside the JVM |
| | |
| | | /** |
| | | * Finds the domain for a given DN. |
| | | * |
| | | * @param dn The DN for which the domain must be returned. |
| | | * @param op An optional operation for which the check is done. |
| | | * Can be null is the request has no associated operation. |
| | | * @return The domain for this DN. |
| | | * @param dn The DN for which the domain must be returned. |
| | | * @param pluginOp An optional operation for which the check is done. |
| | | * Can be null is the request has no associated operation. |
| | | * @return The domain for this DN. |
| | | */ |
| | | public static ReplicationDomain findDomain(DN dn, PluginOperation op) |
| | | public static ReplicationDomain findDomain(DN dn, PluginOperation pluginOp) |
| | | { |
| | | /* |
| | | * Don't run the special replication code on Operation that are |
| | | * specifically marked as don't synchronize. |
| | | */ |
| | | if ((op != null) && (op instanceof Operation) && |
| | | (((Operation) op).dontSynchronize())) |
| | | return null; |
| | | if ((pluginOp != null) && (pluginOp instanceof Operation)) |
| | | { |
| | | Operation op = ((Operation) pluginOp); |
| | | |
| | | if (op.dontSynchronize()) |
| | | return null; |
| | | |
| | | /* |
| | | * Check if the provided operation is a repair operation and set |
| | | * the synchronization flags if necessary. |
| | | * The repair operations are tagged as synchronization operations |
| | | * so that the core server let the operation modify the entryuuid |
| | | * and ds-sync-hist attributes. |
| | | * They are also tagged as dontSynchronize so that the replication |
| | | * code running later do not generate ChnageNumber, solve conflicts |
| | | * and forward the operation to the replication server. |
| | | */ |
| | | for (Control c : op.getRequestControls()) |
| | | { |
| | | if (c.getOID().equals(OID_REPLICATION_REPAIR_CONTROL)) |
| | | { |
| | | op.setSynchronizationOperation(true); |
| | | op.setDontSynchronize(true); |
| | | // remove this control from the list of controls since |
| | | // it has now been processed and the local backend will |
| | | // fail if it finds a control that it does not know about and |
| | | // that is marked as critical. |
| | | List<Control> controls = op.getRequestControls(); |
| | | controls.remove(c); |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | ReplicationDomain domain = null; |
| | | DN temp = dn; |
| | |
| | | DirectoryServer.registerRestoreTaskListener(this); |
| | | DirectoryServer.registerExportTaskListener(this); |
| | | DirectoryServer.registerImportTaskListener(this); |
| | | |
| | | DirectoryServer.registerSupportedControl( |
| | | ReplicationRepairRequestControl.OID_REPLICATION_REPAIR_CONTROL); |
| | | } |
| | | |
| | | /** |
| | |
| | | op.run(); |
| | | |
| | | ResultCode result = op.getResultCode(); |
| | | if (result != ResultCode.SUCCESS) |
| | | if ((result != ResultCode.SUCCESS) && |
| | | ((result != ResultCode.NO_SUCH_OBJECT))) |
| | | { |
| | | Message message = ERR_ERROR_UPDATING_RUV.get( |
| | | Message message = DEBUG_ERROR_UPDATING_RUV.get( |
| | | op.getResultCode().getResultCodeName().toString(), |
| | | op.toString(), |
| | | op.getErrorMessage().toString(), |
| | |
| | | * An error happened trying to search for the updates |
| | | * This server will start acepting again new updates but |
| | | * some inconsistencies will stay between servers. |
| | | * TODO : REPAIR : log an error for the repair tool |
| | | * Log an error for the repair tool |
| | | * that will need to resynchronize the servers. |
| | | */ |
| | | Message message = NOTE_CANNOT_RECOVER_CHANGES.get(); |
| | | Message message = ERR_CANNOT_RECOVER_CHANGES.get( |
| | | baseDn.toNormalizedString()); |
| | | logError(message); |
| | | } |
| | | else |
| | |
| | | { |
| | | // Continue with the next change but the servers could now become |
| | | // inconsistent. |
| | | // TODO : REPAIR : Should let the repair tool know about this |
| | | Message message = ERR_LOOP_REPLAYING_OPERATION.get(op.toString()); |
| | | // Let the repair tool know about this. |
| | | Message message = ERR_LOOP_REPLAYING_OPERATION.get(op.toString(), |
| | | op.getErrorMessage().toString()); |
| | | logError(message); |
| | | numUnresolvedNamingConflicts.incrementAndGet(); |
| | | |
| | |
| | | * An Exception happened during the replay process. |
| | | * Continue with the next change but the servers will now start |
| | | * to be inconsistent. |
| | | * TODO : REPAIR : Should let the repair tool know about this |
| | | * Let the repair tool know about this. |
| | | */ |
| | | Message message = ERR_EXCEPTION_REPLAYING_OPERATION.get( |
| | | stackTraceToSingleLineString(e), op.toString()); |
| | |
| | | else |
| | | { |
| | | // The other type of errors can not be caused by naming conflicts. |
| | | // TODO log a message for the repair tool. |
| | | // 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; |
| | | } |
| | | } |
| | |
| | | else |
| | | { |
| | | // The other type of errors can not be caused by naming conflicts. |
| | | // TODO log a message for the repair tool. |
| | | // 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; |
| | | } |
| | | } |
| | |
| | | else |
| | | { |
| | | // The other type of errors can not be caused by naming conflicts. |
| | | // TODO log a message for the repair tool. |
| | | // 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; |
| | | } |
| | | } |
| | |
| | | else |
| | | { |
| | | // The other type of errors can not be caused by naming conflicts. |
| | | // TODO log a message for the repair tool. |
| | | // 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; |
| | | } |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | // log error and information for the REPAIR tool. |
| | | MessageBuilder mb = new MessageBuilder(); |
| | | mb.append(ERR_CANNOT_RENAME_CONFLICT_ENTRY.get()); |
| | | mb.append(String.valueOf(entryDN)); |
| | |
| | | mb.append(" "); |
| | | mb.append(String.valueOf(op.getResultCode())); |
| | | logError(mb.toMessage()); |
| | | // TODO : log error and information for the REPAIR tool. |
| | | } |
| | | } catch (DirectoryException e) |
| | | { |
| | | // log errror and information for the REPAIR tool. |
| | | MessageBuilder mb = new MessageBuilder(); |
| | | mb.append(ERR_EXCEPTION_RENAME_CONFLICT_ENTRY.get()); |
| | | mb.append(String.valueOf(entryDN)); |
| | |
| | | mb.append(" "); |
| | | mb.append(e.getLocalizedMessage()); |
| | | logError(mb.toMessage()); |
| | | // TODO log errror and information for the REPAIR tool. |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | if (newOp.getResultCode() != ResultCode.SUCCESS) |
| | | { |
| | | // log information for the repair tool. |
| | | MessageBuilder mb = new MessageBuilder(); |
| | | mb.append(ERR_CANNOT_RENAME_CONFLICT_ENTRY.get()); |
| | | mb.append(String.valueOf(dn)); |
| | |
| | | mb.append(" "); |
| | | mb.append(String.valueOf(newOp.getResultCode())); |
| | | logError(mb.toMessage()); |
| | | /* |
| | | * TODO : REPAIR should log information for the repair tool. |
| | | */ |
| | | } |
| | | } |
| | | |
| | |
| | | ModifyOperation newOp = conn.processModify(currentDN, mods); |
| | | if (newOp.getResultCode() != ResultCode.SUCCESS) |
| | | { |
| | | // Log information for the repair tool. |
| | | MessageBuilder mb = new MessageBuilder(); |
| | | mb.append(ERR_CANNOT_ADD_CONFLICT_ATTRIBUTE.get()); |
| | | mb.append(String.valueOf(op)); |
| | | mb.append(" "); |
| | | mb.append(String.valueOf(newOp.getResultCode())); |
| | | logError(mb.toMessage()); |
| | | /* |
| | | * TODO : REPAIR should log information for the repair tool. |
| | | */ |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.LDAPException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class implements the Sun-defined replication repair control. |
| | | * This control can be used to modify the content of a replicated database |
| | | * on a single server without impacting the other servers that are replicated |
| | | * with this server. |
| | | * It also allows to modify attributes like entryuuid and ds-sync-hist that |
| | | * are normally not modifiable from an external connection. |
| | | */ |
| | | public class ReplicationRepairRequestControl |
| | | extends Control |
| | | { |
| | | /** |
| | | * The OID of the Replication repair Control. |
| | | */ |
| | | public static final String |
| | | OID_REPLICATION_REPAIR_CONTROL = "1.3.6.1.4.1.26027.1.5.2"; |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of the replication repair request control with the |
| | | * default settings. |
| | | */ |
| | | public ReplicationRepairRequestControl() |
| | | { |
| | | super(OID_REPLICATION_REPAIR_CONTROL, false); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of the replication repair control with the |
| | | * provided information. |
| | | * |
| | | * @param oid The OID to use for this control. |
| | | * @param isCritical Indicates whether support for this control should be |
| | | * considered a critical part of the client processing. |
| | | */ |
| | | public ReplicationRepairRequestControl(String oid, boolean isCritical) |
| | | { |
| | | super(oid, isCritical); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new replication repair request control from the contents of the |
| | | * provided control. |
| | | * |
| | | * @param control The generic control containing the information to use to |
| | | * create this replication repair request control. |
| | | * |
| | | * @return The replication repair request control decoded from the provided |
| | | * control. |
| | | * |
| | | * @throws LDAPException If this control cannot be decoded as a valid |
| | | * replication repair request control. |
| | | */ |
| | | public static ReplicationRepairRequestControl decodeControl(Control control) |
| | | throws LDAPException |
| | | { |
| | | return new ReplicationRepairRequestControl(control.getOID(), |
| | | control.isCritical()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of this replication repair request |
| | | * control. |
| | | * |
| | | * @return A string representation of this replication repair request |
| | | * control. |
| | | */ |
| | | public String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | toString(buffer); |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends a string representation of this replication repair request control |
| | | * to the provided buffer. |
| | | * |
| | | * @param buffer The buffer to which the information should be appended. |
| | | */ |
| | | public void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("ReplicationRepairRequestControl()"); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public static final String LOG_SEVERITY_ALL = "all"; |
| | | |
| | | /** |
| | | * The English name for the basic none log severity used to log |
| | | * no error message beside some specific category. |
| | | */ |
| | | public static final String LOG_SEVERITY_NONE = "none"; |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | // If the attribute type is marked "NO-USER-MODIFICATION" then fail |
| | | // unless this is an internal operation or is related to |
| | | // synchronization in some way. |
| | | // This must be done before running the password policy code |
| | | // and any other code that may add attributes marked as |
| | | // "NO-USER-MODIFICATION" |
| | | // |
| | | // Note that doing this checks at this time |
| | | // of the processing does not make it possible for pre-parse plugins |
| | | // to add NO-USER-MODIFICATION attributes to the entry. |
| | | for (AttributeType at : userAttributes.keySet()) |
| | | { |
| | | if (at.isNoUserModification()) |
| | | { |
| | | if (! (localOp.isInternalOperation() || |
| | | localOp.isSynchronizationOperation())) |
| | | { |
| | | localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM); |
| | | localOp.appendErrorMessage(ERR_ADD_ATTR_IS_NO_USER_MOD.get( |
| | | String.valueOf(entryDN), at.getNameOrOID())); |
| | | |
| | | break addProcessing; |
| | | } |
| | | } |
| | | } |
| | | |
| | | for (AttributeType at : operationalAttributes.keySet()) |
| | | { |
| | | if (at.isNoUserModification()) |
| | | { |
| | | if (! (localOp.isInternalOperation() || |
| | | localOp.isSynchronizationOperation())) |
| | | { |
| | | localOp.setResultCode(ResultCode.UNWILLING_TO_PERFORM); |
| | | localOp.appendErrorMessage(ERR_ADD_ATTR_IS_NO_USER_MOD.get( |
| | | String.valueOf(entryDN), at.getNameOrOID())); |
| | | |
| | | break addProcessing; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Check to see if the entry already exists. We do this before |
| | | // checking whether the parent exists to ensure a referral entry |
| | |
| | | */ |
| | | protected void configureReplication() throws Exception |
| | | { |
| | | // Add the Multimaster replication plugin |
| | | String synchroPluginLdif = "dn: " + synchroPluginStringDN + "\n" |
| | | + "objectClass: top\n" |
| | | + "objectClass: ds-cfg-synchronization-provider\n" |
| | | + "objectClass: ds-cfg-multimaster-synchronization-provider\n" |
| | | + "ds-cfg-synchronization-provider-enabled: true\n" |
| | | + "ds-cfg-synchronization-provider-class: " + |
| | | "org.opends.server.replication.plugin.MultimasterReplication\n"; |
| | | Entry synchroPluginEntry = TestCaseUtils.entryFromLdifString(synchroPluginLdif); |
| | | DirectoryServer.getConfigHandler().addEntry(synchroPluginEntry, null); |
| | | configEntryList.add(synchroPluginEntry.getDN()); |
| | | assertNotNull(DirectoryServer.getConfigEntry(DN |
| | | .decode(synchroPluginStringDN)), |
| | | "Unable to add the Multimaster replication plugin"); |
| | | |
| | | // domains container entry. |
| | | String domainsLdif = "dn: " |
| | | + "cn=domains," + synchroPluginStringDN + "\n" |
| | | + "objectClass: top\n" |
| | | + "objectClass: ds-cfg-branch\n"; |
| | | Entry domainsEntry = TestCaseUtils.entryFromLdifString(domainsLdif); |
| | | DirectoryServer.getConfigHandler().addEntry(domainsEntry, null); |
| | | configEntryList.add(domainsEntry.getDN()); |
| | | assertNotNull(DirectoryServer.getConfigEntry( |
| | | DN.decode(synchroPluginStringDN)), |
| | | "Unable to add the Multimaster replication plugin"); |
| | | |
| | | if (replServerEntry != null) |
| | | { |
| | | // Add the replication server |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | import org.opends.server.tools.LDAPModify; |
| | | import org.testng.annotations.Test; |
| | | import static org.testng.Assert.*; |
| | | |
| | | public class ReplicationRepairControlTest extends ReplicationTestCase |
| | | { |
| | | @Test() |
| | | public void testRepairControl() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | // Test that we can't add an entry with the entryuuid attribute |
| | | // without specifying the replication repair control. |
| | | String path = TestCaseUtils.createTempFile( |
| | | "dn: uid=test.repair,o=test\n" + |
| | | "changetype: add\n" + |
| | | "objectClass: top\n" + |
| | | "objectClass: person" + |
| | | "objectClass: organizationalPerson" + |
| | | "objectClass: inetOrgPerson" + |
| | | "uid: test.repair" + |
| | | "givenName: Test" + |
| | | "sn: User" + |
| | | "cn: Test User" + |
| | | "userPassword: password" + |
| | | "entryuuid: d5b910d8-47cb-4ac0-9e5f-0f4a77de58d4"); |
| | | |
| | | String[] args = |
| | | { |
| | | "-h", "127.0.0.1", |
| | | "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), |
| | | "-D", "cn=Directory Manager", |
| | | "-w", "password", |
| | | "-a", |
| | | "-f", path |
| | | }; |
| | | |
| | | assertEquals(LDAPModify.mainModify(args, false, null, null), 65); |
| | | |
| | | // Test that we can't add an entry with the ds-sync-hist attribute |
| | | // without specifying the replication repair control. |
| | | String path1 = TestCaseUtils.createTempFile( |
| | | "dn: uid=test.repair,o=test\n" + |
| | | "changetype: add\n" + |
| | | "objectClass: top\n" + |
| | | "objectClass: person" + |
| | | "objectClass: organizationalPerson" + |
| | | "objectClass: inetOrgPerson" + |
| | | "uid: test.repair" + |
| | | "givenName: Test" + |
| | | "sn: User" + |
| | | "cn: Test User" + |
| | | "userPassword: password" + |
| | | "ds-sync-hist: description:00000108b3a6cbb800000001:del:deleted_value"); |
| | | |
| | | String[] args1 = |
| | | { |
| | | "-h", "127.0.0.1", |
| | | "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), |
| | | "-D", "cn=Directory Manager", |
| | | "-w", "password", |
| | | "-a", |
| | | "-f", path1 |
| | | }; |
| | | |
| | | |
| | | assertEquals(LDAPModify.mainModify(args1, false, null, null), 65); |
| | | |
| | | // Now Test specifying the replication repair control makes |
| | | // possible to add an entry with the entryuuid and ds-sync-hist attributes |
| | | // (notice the -J repairControlOid in the ldapmodify arguments) |
| | | String path2 = TestCaseUtils.createTempFile( |
| | | "dn: uid=test.repair,o=test\n" + |
| | | "changetype: add\n" + |
| | | "objectClass: top\n" + |
| | | "objectClass: person" + |
| | | "objectClass: organizationalPerson" + |
| | | "objectClass: inetOrgPerson" + |
| | | "uid: test.repair" + |
| | | "givenName: Test" + |
| | | "sn: User" + |
| | | "cn: Test User" + |
| | | "userPassword: password" + |
| | | "ds-sync-hist: description:00000108b3a6cbb800000001:del:deleted_value" + |
| | | "entryuuid: d5b910d8-47cb-4ac0-9e5f-0f4a77de58d4"); |
| | | |
| | | String[] args2 = |
| | | { |
| | | "-h", "127.0.0.1", |
| | | "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), |
| | | "-D", "cn=Directory Manager", |
| | | "-w", "password", |
| | | "-J", "1.3.6.1.4.1.26027.1.5.2", |
| | | "-a", |
| | | "-f", path2 |
| | | }; |
| | | |
| | | assertEquals(LDAPModify.mainModify(args2, false, null, null), 0); |
| | | } |
| | | } |