mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
24.56.2013 af76a3750288d90c006022829887c92601a4737c
OPENDJ-885 - Replication replay may lose changes if it can't acquire a writeLock

Review: Matthew Swift, Ludovic Poitou, Christophe Sovant

1st phase of the changes.

LockManager.java:
Tripled the wait time for trying to acquire a lock.

*.java:
Removed the triple attempts at locking anti pattern.

PasswordModifyExtendedOperation.java:
Extracted method toAttributeValues() from processExtendedOperation().
20 files modified
808 ■■■■ changed files
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java 37 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/TaskBackend.java 81 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/TaskScheduler.java 44 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java 36 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java 32 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java 36 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java 84 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java 23 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/SASLContext.java 28 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/SubjectEqualsDNCertificateMapper.java 35 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java 20 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/Entry.java 35 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/LockManager.java 10 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java 44 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java 31 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java 27 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java 30 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java 45 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java 34 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java 96 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -23,7 +23,7 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2012 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2013 Manuel Gaupp
 */
package org.opends.server.authorization.dseecompat;
@@ -61,30 +61,7 @@
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.AttributeValues;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LockManager;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.Operation;
import org.opends.server.types.Privilege;
import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.SearchScope;
import org.opends.server.types.*;
import org.opends.server.workflowelement.localbackend.*;
@@ -1096,15 +1073,7 @@
      LocalBackendModifyDNOperation op) throws DirectoryException
  {
    boolean ret = false;
    Lock entryLock = null;
    for (int i = 0; i < 3; i++)
    {
      entryLock = LockManager.lockRead(superiorDN);
      if (entryLock != null)
      {
        break;
      }
    }
    final Lock entryLock = LockManager.lockRead(superiorDN);
    if (entryLock == null)
    {
      Message message =
opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -23,87 +23,42 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.backends.task;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.*;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.crypto.Mac;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.TaskBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
import org.opends.server.config.ConfigEntry;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.config.ConfigException;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.BackupInfo;
import org.opends.server.types.CanceledOperationException;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.CryptoManager;
import org.opends.server.types.CryptoManagerException;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.LockManager;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.util.DynamicConstants;
import org.opends.server.util.LDIFException;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.Validator;
import org.opends.server.types.*;
import org.opends.server.util.*;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -711,18 +666,10 @@
    Lock entryLock = null;
    if (! taskScheduler.holdsSchedulerLock())
    {
      for (int i=0; i < 3; i++)
      {
        entryLock = LockManager.lockWrite(entryDN);
        if (entryLock != null)
        {
          break;
        }
      }
      entryLock = LockManager.lockWrite(entryDN);
      if (entryLock == null)
      {
        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
        throw new DirectoryException(ResultCode.BUSY,
                                     ERR_TASKBE_MODIFY_CANNOT_LOCK_ENTRY.get(
                                          String.valueOf(entryDN)));
      }
@@ -2043,6 +1990,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isConfigurationChangeAcceptable(TaskBackendCfg configEntry,
                                            List<Message> unacceptableReasons)
  {
@@ -2140,6 +2088,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(TaskBackendCfg configEntry)
  {
    ResultCode         resultCode          = ResultCode.SUCCESS;
opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS
 */
package org.opends.server.backends.task;
@@ -37,15 +38,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -56,22 +49,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Attributes;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LockManager;
import org.opends.server.types.Operation;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.*;
import org.opends.server.util.LDIFException;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.LDIFWriter;
@@ -1697,18 +1675,11 @@
  Lock readLockEntry(DN entryDN)
       throws DirectoryException
  {
    Lock lock = LockManager.lockRead(entryDN);
    for (int i=0; ((lock == null) && (i < 4)); i++)
    {
      lock = LockManager.lockRead(entryDN);
    }
    final Lock lock = LockManager.lockRead(entryDN);
    if (lock == null)
    {
      Message message =
          ERR_BACKEND_CANNOT_LOCK_ENTRY.get(String.valueOf(entryDN));
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
                                   message);
      throw new DirectoryException(ResultCode.BUSY,
          ERR_BACKEND_CANNOT_LOCK_ENTRY.get(String.valueOf(entryDN)));
    }
    else
    {
@@ -2138,6 +2109,7 @@
   * @return  The DN of the configuration entry with which this alert generator
   *          is associated.
   */
  @Override
  public DN getComponentEntryDN()
  {
    return taskBackend.getConfigEntryDN();
@@ -2152,6 +2124,7 @@
   * @return  The fully-qualified name of the Java class for this alert
   *          generator implementation.
   */
  @Override
  public String getClassName()
  {
    return CLASS_NAME;
@@ -2169,6 +2142,7 @@
   * @return  Information about the set of alerts that this generator may
   *          produce.
   */
  @Override
  public LinkedHashMap<String,String> getAlerts()
  {
    LinkedHashMap<String,String> alerts = new LinkedHashMap<String,String>();
opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
@@ -23,31 +23,29 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 *      Portions copyright 2011-2013 ForgeRock AS.
 */
package org.opends.server.controls;
import org.opends.messages.Message;
import java.util.concurrent.locks.Lock;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
import org.opends.server.api.AuthenticationPolicyState;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.protocols.asn1.ASN1Constants.
    UNIVERSAL_OCTET_STRING_TYPE;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.protocols.asn1.ASN1Constants.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class implements version 1 of the proxied authorization control as
 * defined in early versions of draft-weltman-ldapv3-proxy (this implementation
@@ -69,6 +67,7 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public ProxiedAuthV1Control decode(boolean isCritical, ByteString value)
        throws DirectoryException
    {
@@ -107,6 +106,7 @@
      return new ProxiedAuthV1Control(isCritical, authorizationDN);
    }
    @Override
    public String getOID()
    {
      return OID_PROXIED_AUTH_V1;
@@ -294,21 +294,11 @@
    }
    Lock entryLock = null;
    for (int i=0; i < 3; i++)
    {
      entryLock = LockManager.lockRead(authzDN);
      if (entryLock != null)
      {
        break;
      }
    }
    final Lock entryLock = LockManager.lockRead(authzDN);
    if (entryLock == null)
    {
      Message message =
          ERR_PROXYAUTH1_CANNOT_LOCK_USER.get(String.valueOf(authzDN));
      throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
      throw new DirectoryException(ResultCode.BUSY,
          ERR_PROXYAUTH1_CANNOT_LOCK_USER.get(String.valueOf(authzDN)));
    }
    try
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -26,27 +26,26 @@
 *      Portions copyright 2011-2013 ForgeRock AS.
 */
package org.opends.server.controls;
import org.opends.messages.Message;
import java.util.concurrent.locks.Lock;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
import org.opends.server.api.AuthenticationPolicyState;
import org.opends.server.api.IdentityMapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.protocols.asn1.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.ensureNotNull;
import static org.opends.server.util.Validator.*;
/**
 * This class implements version 2 of the proxied authorization control as
@@ -247,22 +246,11 @@
          authzDN = actualDN;
        }
        Lock entryLock = null;
        for (int i=0; i < 3; i++)
        {
          entryLock = LockManager.lockRead(authzDN);
          if (entryLock != null)
          {
            break;
          }
        }
        final Lock entryLock = LockManager.lockRead(authzDN);
        if (entryLock == null)
        {
          Message message =
              ERR_PROXYAUTH2_CANNOT_LOCK_USER.get(String.valueOf(authzDN));
          throw new DirectoryException(
                  ResultCode.AUTHORIZATION_DENIED, message);
          throw new DirectoryException(ResultCode.BUSY,
              ERR_PROXYAUTH2_CANNOT_LOCK_USER.get(String.valueOf(authzDN)));
        }
        try
opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
@@ -23,7 +23,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 *      Portions copyright 2011-2013 ForgeRock AS.
 */
package org.opends.server.extensions;
@@ -47,24 +47,13 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LockManager;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class provides an implementation of a SASL mechanism that uses digest
 * authentication via CRAM-MD5.  This is a password-based mechanism that does
@@ -349,23 +338,12 @@
      // Acquire a read lock on the user entry.  If this fails, then so will the
      // authentication.
      Lock readLock = null;
      for (int i=0; i < 3; i++)
      {
        readLock = LockManager.lockRead(userDN);
        if (readLock != null)
        {
          break;
        }
      }
      final Lock readLock = LockManager.lockRead(userDN);
      if (readLock == null)
      {
        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
        Message message = INFO_SASLCRAMMD5_CANNOT_LOCK_ENTRY.get(
                String.valueOf(userDN));
        bindOperation.setAuthFailureReason(message);
        bindOperation.setResultCode(ResultCode.BUSY);
        bindOperation.setAuthFailureReason(INFO_SASLCRAMMD5_CANNOT_LOCK_ENTRY
            .get(String.valueOf(userDN)));
        return;
      }
@@ -614,6 +592,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isConfigurationChangeAcceptable(
                      CramMD5SASLMechanismHandlerCfg configuration,
                      List<Message> unacceptableReasons)
@@ -626,6 +605,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(
              CramMD5SASLMechanismHandlerCfg configuration)
  {
opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -23,50 +23,45 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.extensions;
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.ExtendedOperationHandlerCfg;
import org.opends.server.admin.std.server.
            PasswordModifyExtendedOperationHandlerCfg;
import org.opends.server.api.*;
import org.opends.server.config.ConfigException;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
import org.opends.server.controls.PasswordPolicyWarningType;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ExtendedOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.*;
import org.opends.server.protocols.asn1.ASN1;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.UserPasswordSyntax;
import org.opends.server.types.*;
import static org.opends.messages.CoreMessages.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.ErrorLogger;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.messages.CoreMessages.*;
import org.opends.messages.MessageBuilder;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class implements the password modify extended operation defined in RFC
 * 3062.  It includes support for requiring the user's current password as well
@@ -166,6 +161,7 @@
   *                                   that is not related to the server
   *                                   configuration.
   */
  @Override
  public void initializeExtendedOperationHandler(
       PasswordModifyExtendedOperationHandlerCfg config)
         throws ConfigException, InitializationException
@@ -244,6 +240,7 @@
   *
   * @param  operation  The extended operation to be processed.
   */
  @Override
  public void processExtendedOperation(ExtendedOperation operation)
  {
    // Initialize the variables associated with components that may be included
@@ -353,25 +350,12 @@
        // Retrieve a write lock on that user's entry.
        userDN = requestorEntry.getDN();
        for (int i=0; i < 3; i++)
        {
          userLock = LockManager.lockWrite(userDN);
          if (userLock != null)
          {
            break;
          }
        }
        userLock = LockManager.lockWrite(userDN);
        if (userLock == null)
        {
          operation.setResultCode(DirectoryServer.getServerErrorResultCode());
          Message message =
                  ERR_EXTOP_PASSMOD_CANNOT_LOCK_USER_ENTRY.get(
                          String.valueOf(userDN));
          operation.appendErrorMessage(message);
          operation.setResultCode(ResultCode.BUSY);
          operation.appendErrorMessage(ERR_EXTOP_PASSMOD_CANNOT_LOCK_USER_ENTRY
              .get(String.valueOf(userDN)));
          return;
        }
@@ -1024,31 +1008,15 @@
        modList.add(new Modification(ModificationType.DELETE, deleteAttr));
        // Add the new encoded values.
        LinkedHashSet<AttributeValue> addValues =
             new LinkedHashSet<AttributeValue>(encodedPasswords.size());
        for (ByteString s : encodedPasswords)
        {
          addValues.add(AttributeValues.create(attrType, s));
        }
        builder = new AttributeBuilder(attrType);
        builder.addAll(addValues);
        builder.addAll(toAttributeValues(attrType, encodedPasswords));
        Attribute addAttr = builder.toAttribute();
        modList.add(new Modification(ModificationType.ADD, addAttr));
      }
      else
      {
        LinkedHashSet<AttributeValue> replaceValues =
             new LinkedHashSet<AttributeValue>(encodedPasswords.size());
        for (ByteString s : encodedPasswords)
        {
          replaceValues.add(
              AttributeValues.create(attrType, s));
        }
        AttributeBuilder builder = new AttributeBuilder(attrType);
        builder.addAll(replaceValues);
        builder.addAll(toAttributeValues(attrType, encodedPasswords));
        Attribute addAttr = builder.toAttribute();
        modList.add(new Modification(ModificationType.REPLACE, addAttr));
      }
@@ -1241,7 +1209,17 @@
    }
  }
  private Collection<AttributeValue> toAttributeValues(AttributeType attrType,
      Collection<ByteString> values)
  {
    Set<AttributeValue> results =
        new LinkedHashSet<AttributeValue>(values.size());
    for (ByteString s : values)
    {
      results.add(AttributeValues.create(attrType, s));
    }
    return results;
  }
  /**
   * Retrieves the entry for the specified user based on the provided DN.  If
@@ -1348,6 +1326,7 @@
   * @return  <CODE>true</CODE> if the provided entry has an acceptable
   *          configuration for this component, or <CODE>false</CODE> if not.
   */
  @Override
  public boolean isConfigurationChangeAcceptable(
       PasswordModifyExtendedOperationHandlerCfg config,
       List<Message> unacceptableReasons)
@@ -1401,6 +1380,7 @@
   *
   * @return  Information about the result of the configuration update.
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(
       PasswordModifyExtendedOperationHandlerCfg config)
  {
opends/src/server/org/opends/server/extensions/PlainSASLMechanismHandler.java
@@ -76,10 +76,10 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The identity mapper that will be used to map ID strings to user entries.
  /** The identity mapper that will be used to map ID strings to user entries.*/
  private IdentityMapper<?> identityMapper;
  // The current configuration for this SASL mechanism handler.
  /** The current configuration for this SASL mechanism handler. */
  private PlainSASLMechanismHandlerCfg currentConfig;
@@ -247,23 +247,12 @@
      // Acquire a read lock on the user entry.  If this fails, then so will the
      // authentication.
      Lock readLock = null;
      for (int i=0; i < 3; i++)
      {
        readLock = LockManager.lockRead(userDN);
        if (readLock != null)
        {
          break;
        }
      }
      final Lock readLock = LockManager.lockRead(userDN);
      if (readLock == null)
      {
        bindOperation.setResultCode(DirectoryServer.getServerErrorResultCode());
        Message message = INFO_SASLPLAIN_CANNOT_LOCK_ENTRY.get(String.valueOf(
                userDN));
        bindOperation.setAuthFailureReason(message);
        bindOperation.setResultCode(ResultCode.BUSY);
        bindOperation.setAuthFailureReason(INFO_SASLPLAIN_CANNOT_LOCK_ENTRY
            .get(String.valueOf(userDN)));
        return;
      }
opends/src/server/org/opends/server/extensions/SASLContext.java
@@ -23,21 +23,14 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions copyright 2011-2012 ForgeRock AS.
 *      Portions copyright 2011-2013 ForgeRock AS.
 */
package org.opends.server.extensions;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.util.ServerConstants.SASL_DEFAULT_PROTOCOL;
import static org.opends.server.util.ServerConstants.SASL_MECHANISM_DIGEST_MD5;
import static org.opends.server.util.ServerConstants.SASL_MECHANISM_GSSAPI;
import static org.opends.server.util.StaticUtils.getExceptionMessage;
import static org.opends.server.util.StaticUtils.toLowerCase;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -188,6 +181,7 @@
   * @throws UnsupportedCallbackException
   *           If a callback is not supported.
   */
  @Override
  public void handle(final Callback[] callbacks)
      throws UnsupportedCallbackException
  {
@@ -227,6 +221,7 @@
   *
   * @return {@code true} if the authentication processing was successful.
   */
  @Override
  public Boolean run()
  {
    final ClientConnection clientConn = bindOp.getClientConnection();
@@ -905,16 +900,7 @@
   */
  private void getAuthEntry(final DN userDN)
  {
    Lock readLock = null;
    for (int i = 0; i < 3; i++)
    {
      readLock = LockManager.lockRead(userDN);
      if (readLock != null)
      {
        break;
      }
    }
    final Lock readLock = LockManager.lockRead(userDN);
    if (readLock == null)
    {
      setCallbackMsg(INFO_SASL_CANNOT_LOCK_ENTRY.get(String.valueOf(userDN)));
opends/src/server/org/opends/server/extensions/SubjectEqualsDNCertificateMapper.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -30,29 +31,22 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import java.util.concurrent.locks.Lock;
import javax.security.auth.x500.X500Principal;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.SubjectEqualsDNCertificateMapperCfg;
import org.opends.server.api.CertificateMapper;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LockManager;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class implements a very simple Directory Server certificate mapper that
 * will map a certificate to a user only if the subject of the peer certificate
@@ -74,7 +68,6 @@
  public SubjectEqualsDNCertificateMapper()
  {
    super();
  }
@@ -82,6 +75,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeCertificateMapper(SubjectEqualsDNCertificateMapperCfg
                                               configuration)
         throws ConfigException, InitializationException
@@ -111,6 +105,7 @@
   *                              error message should be returned to the
   *                              client.
   */
  @Override
  public Entry mapCertificateToUser(Certificate[] certificateChain)
         throws DirectoryException
  {
@@ -163,21 +158,11 @@
    // Acquire a read lock on the user entry.  If this fails, then so will the
    // certificate mapping.
    Lock readLock = null;
    for (int i=0; i < 3; i++)
    {
      readLock = LockManager.lockRead(subjectDN);
      if (readLock != null)
      {
        break;
      }
    }
    final Lock readLock = LockManager.lockRead(subjectDN);
    if (readLock == null)
    {
      Message message =
          ERR_SEDCM_CANNOT_LOCK_ENTRY.get(String.valueOf(subjectDN));
      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, message);
      throw new DirectoryException(ResultCode.BUSY, ERR_SEDCM_CANNOT_LOCK_ENTRY
          .get(String.valueOf(subjectDN)));
    }
opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java
@@ -27,14 +27,13 @@
 */
package org.opends.server.tasks;
import org.opends.messages.Message;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.SynchronizationProviderCfg;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.SynchronizationProvider;
@@ -43,17 +42,15 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SchemaConfigManager;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import static org.opends.messages.TaskMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.messages.TaskMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class provides an implementation of a Directory Server task that can be
 * used to add the contents of a new schema file into the server schema.
@@ -66,12 +63,13 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The list of files to be added to the server schema.
  /** The list of files to be added to the server schema. */
  TreeSet<String> filesToAdd;
  /**
   * {@inheritDoc}
   */
  @Override
  public Message getDisplayName() {
    return INFO_TASK_ADD_SCHEMA_FILE_NAME.get();
  }
@@ -195,17 +193,13 @@
  /**
   * {@inheritDoc}
   */
  @Override
  protected TaskState runTask()
  {
    // Obtain a write lock on the server schema so that we can be sure nothing
    // else tries to write to it at the same time.
    DN schemaDN = DirectoryServer.getSchemaDN();
    Lock schemaLock = LockManager.lockWrite(schemaDN);
    for (int i=0; ((schemaLock == null) && (i < 3)); i++)
    {
      schemaLock = LockManager.lockWrite(schemaDN);
    }
    final Lock schemaLock = LockManager.lockWrite(schemaDN);
    if (schemaLock == null)
    {
      Message message = ERR_TASK_ADDSCHEMAFILE_CANNOT_LOCK_SCHEMA.get(
opends/src/server/org/opends/server/types/Entry.java
@@ -29,17 +29,7 @@
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
@@ -65,7 +55,6 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a data structure for a Directory Server entry.
 * It includes a DN and a set of attributes.
@@ -2555,16 +2544,7 @@
        if (parentDN != null)
        {
          // Get the parent entry and check its structural class.
          Lock lock = null;
          for (int i=0; i < 3; i++)
          {
            lock = LockManager.lockRead(parentDN);
            if (lock != null)
            {
              break;
            }
          }
          final Lock lock = LockManager.lockRead(parentDN);
          if (lock == null)
          {
            Message message =
@@ -2667,16 +2647,7 @@
        if (parentDN != null)
        {
          // Get the parent entry and check its structural class.
          Lock lock = null;
          for (int i=0; i < 3; i++)
          {
            lock = LockManager.lockRead(parentDN);
            if (lock != null)
            {
              break;
            }
          }
          final Lock lock = LockManager.lockRead(parentDN);
          if (lock == null)
          {
            Message message =
opends/src/server/org/opends/server/types/LockManager.java
@@ -27,8 +27,6 @@
 */
package org.opends.server.types;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@@ -39,8 +37,6 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
/**
 * This class defines a Directory Server component that can keep track
 * of all locks needed throughout the Directory Server.  It is
@@ -89,15 +85,15 @@
   * The default length of time in milliseconds to wait while
   * attempting to acquire a read or write lock.
   */
  public static final long DEFAULT_TIMEOUT = 3000;
  public static final long DEFAULT_TIMEOUT = 9000;
  // The set of entry locks that the server knows about.
  /** The set of entry locks that the server knows about. */
  private static
       ConcurrentHashMap<DN,ReentrantReadWriteLock> lockTable;
  // Whether fair ordering should be used on the locks.
  /** Whether fair ordering should be used on the locks. */
  private static boolean fair;
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -23,7 +23,7 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2012 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
@@ -46,19 +46,8 @@
import org.opends.messages.MessageBuilder;
import org.opends.server.api.*;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.AddOperation;
import org.opends.server.core.AddOperationWrapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicy;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.controls.*;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.UserPasswordSyntax;
@@ -152,6 +141,7 @@
   * @return  The entry to be added to the server, or <CODE>null</CODE> if it is
   *          not yet available.
   */
  @Override
  public final Entry getEntryToAdd()
  {
    return entry;
@@ -234,21 +224,12 @@
        // always released when exiting this method, no matter what.  Since
        // the entry shouldn't exist yet, locking earlier than necessary
        // shouldn't cause a problem.
        for (int i=0; i < 3; i++)
        {
          entryLock = LockManager.lockWrite(entryDN);
          if (entryLock != null)
          {
            break;
          }
        }
        entryLock = LockManager.lockWrite(entryDN);
        if (entryLock == null)
        {
          setResultCode(DirectoryServer.getServerErrorResultCode());
          setResultCode(ResultCode.BUSY);
          appendErrorMessage(ERR_ADD_CANNOT_LOCK_ENTRY.get(
                                  String.valueOf(entryDN)));
          break addProcessing;
        }
@@ -751,6 +732,7 @@
    {
      registerPostResponseCallback(new Runnable()
      {
        @Override
        public void run()
        {
          // Notify persistent searches.
@@ -823,18 +805,10 @@
    }
    else
    {
      for (int i=0; i < 3; i++)
      {
        parentLock = LockManager.lockRead(parentDN);
        if (parentLock != null)
        {
          break;
        }
      }
      parentLock = LockManager.lockRead(parentDN);
      if (parentLock == null)
      {
        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
        throw new DirectoryException(ResultCode.BUSY,
                                     ERR_ADD_CANNOT_LOCK_PARENT.get(
                                          String.valueOf(entryDN),
                                          String.valueOf(parentDN)));
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -27,8 +27,6 @@
 */
package org.opends.server.workflowelement.localbackend;
import java.util.List;
import java.util.concurrent.locks.Lock;
@@ -38,19 +36,8 @@
import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn;
import org.opends.server.api.*;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.AuthorizationIdentityResponseControl;
import org.opends.server.controls.PasswordExpiredControl;
import org.opends.server.controls.PasswordExpiringControl;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
import org.opends.server.controls.PasswordPolicyWarningType;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.BindOperation;
import org.opends.server.core.BindOperationWrapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicy;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.controls.*;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationBindOperation;
@@ -64,7 +51,6 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to bind against the Directory Server,
 * with the bound user entry within a local backend.
@@ -468,19 +454,10 @@
    // Get the user entry based on the bind DN.  If it does not exist,
    // then fail.
    Lock userLock = null;
    for (int i=0; i < 3; i++)
    {
      userLock = LockManager.lockRead(bindDN);
      if (userLock != null)
      {
        break;
      }
    }
    final Lock userLock = LockManager.lockRead(bindDN);
    if (userLock == null)
    {
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
      throw new DirectoryException(ResultCode.BUSY,
                                   ERR_BIND_OPERATION_CANNOT_LOCK_USER.get(
                                        String.valueOf(bindDN)));
    }
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -23,12 +23,10 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2012 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.Lock;
@@ -39,11 +37,7 @@
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.CompareOperation;
import org.opends.server.core.CompareOperationWrapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationCompareOperation;
@@ -54,8 +48,6 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
/**
 * This class defines an operation that may be used to determine whether a
 * specified entry in the Directory Server contains a given attribute-value
@@ -114,6 +106,7 @@
   * @return  The entry to target with the compare operation, or
   *          <CODE>null</CODE> if the entry is not yet available.
   */
  @Override
  public Entry getEntryToCompare()
  {
    return entry;
@@ -180,22 +173,12 @@
      // Grab a read lock on the entry.
      Lock readLock = null;
      for (int i=0; i < 3; i++)
      {
        readLock = LockManager.lockRead(entryDN);
        if (readLock != null)
        {
          break;
        }
      }
      final Lock readLock = LockManager.lockRead(entryDN);
      if (readLock == null)
      {
        setResultCode(DirectoryServer.getServerErrorResultCode());
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(
                                String.valueOf(entryDN)));
        break compareProcessing;
      }
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -23,12 +23,10 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2012 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import java.util.List;
import java.util.concurrent.locks.Lock;
@@ -39,18 +37,13 @@
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.*;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DeleteOperationWrapper;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationDeleteOperation;
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PreOperationDeleteOperation;
import org.opends.server.types.operation.PostSynchronizationDeleteOperation;
import org.opends.server.types.operation.PreOperationDeleteOperation;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
@@ -58,8 +51,6 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to delete an entry in a local backend
 * of the Directory Server.
@@ -127,6 +118,7 @@
   * @return  The entry to be deleted, or <CODE>null</CODE> if the entry is not
   *          yet available.
   */
  @Override
  public Entry getEntryToDelete()
  {
    return entry;
@@ -169,19 +161,10 @@
      }
      // Grab a write lock on the entry.
      Lock entryLock = null;
      for (int i=0; i < 3; i++)
      {
        entryLock = LockManager.lockWrite(entryDN);
        if (entryLock != null)
        {
          break;
        }
      }
      final Lock entryLock = LockManager.lockWrite(entryDN);
      if (entryLock == null)
      {
        setResultCode(DirectoryServer.getServerErrorResultCode());
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_DELETE_CANNOT_LOCK_ENTRY.get(
                                String.valueOf(entryDN)));
        break deleteProcessing;
@@ -455,6 +438,7 @@
      registerPostResponseCallback(new Runnable()
      {
        @Override
        public void run()
        {
          // Notify persistent searches.
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -23,12 +23,10 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2012 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;
@@ -40,23 +38,14 @@
import org.opends.server.api.ClientConnection;
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.LDAPPreReadRequestControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyDNOperationWrapper;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.controls.*;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationModifyDNOperation;
import org.opends.server.types.operation.PostResponseModifyDNOperation;
import org.opends.server.types.operation.PreOperationModifyDNOperation;
import org.opends.server.types.operation.PostSynchronizationModifyDNOperation;
import org.opends.server.types.operation.PreOperationModifyDNOperation;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
@@ -64,8 +53,6 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to move an entry in a local backend
 * of the Directory Server.
@@ -280,19 +267,10 @@
      // Acquire write locks for the current and new DN.
      Lock currentLock = null;
      for (int i=0; i < 3; i++)
      {
        currentLock = LockManager.lockWrite(entryDN);
        if (currentLock != null)
        {
          break;
        }
      }
      final Lock currentLock = LockManager.lockWrite(entryDN);
      if (currentLock == null)
      {
        setResultCode(DirectoryServer.getServerErrorResultCode());
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(
                                String.valueOf(entryDN)));
        break modifyDNProcessing;
@@ -301,14 +279,7 @@
      Lock newLock = null;
      try
      {
        for (int i=0; i < 3; i++)
        {
          newLock = LockManager.lockWrite(newDN);
          if (newLock != null)
          {
            break;
          }
        }
        newLock = LockManager.lockWrite(newDN);
      }
      catch (Exception e)
      {
@@ -335,7 +306,7 @@
      {
        LockManager.unlock(entryDN, currentLock);
        setResultCode(DirectoryServer.getServerErrorResultCode());
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(
                                String.valueOf(entryDN),
                                String.valueOf(newDN)));
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -46,20 +46,8 @@
import org.opends.messages.MessageBuilder;
import org.opends.server.api.*;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.LDAPPreReadRequestControl;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyOperationWrapper;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.controls.*;
import org.opends.server.core.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.UserPasswordSyntax;
@@ -209,6 +197,7 @@
   * @return  The current entry, or <CODE>null</CODE> if it is not yet
   *          available.
   */
  @Override
  public final Entry getCurrentEntry()
  {
    return currentEntry;
@@ -227,6 +216,7 @@
   *          modify request, or <CODE>null</CODE> if there were none or this
   *          information is not yet available.
   */
  @Override
  public final List<AttributeValue> getCurrentPasswords()
  {
    return currentPasswords;
@@ -243,6 +233,7 @@
   * @return  The modified entry that is to be written to the backend, or
   *          <CODE>null</CODE> if it is not yet available.
   */
  @Override
  public final Entry getModifiedEntry()
  {
    return modifiedEntry;
@@ -260,6 +251,7 @@
   *          request, or <CODE>null</CODE> if there were none or this
   *          information is not yet available.
   */
  @Override
  public final List<AttributeValue> getNewPasswords()
  {
    return newPasswords;
@@ -342,19 +334,10 @@
      checkIfCanceled(false);
      // Acquire a write lock on the target entry.
      Lock entryLock = null;
      for (int i=0; i < 3; i++)
      {
        entryLock = LockManager.lockWrite(entryDN);
        if (entryLock != null)
        {
          break;
        }
      }
      final Lock entryLock = LockManager.lockWrite(entryDN);
      if (entryLock == null)
      {
        setResultCode(DirectoryServer.getServerErrorResultCode());
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODIFY_CANNOT_LOCK_ENTRY.get(
                                String.valueOf(entryDN)));
        break modifyProcessing;
@@ -699,6 +682,7 @@
      registerPostResponseCallback(new Runnable()
      {
        @Override
        public void run()
        {
          // Notify persistent searches.
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java
@@ -70,26 +70,28 @@
import java.util.concurrent.locks.Lock;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import static org.testng.Assert.*;
/**
 * An abstract class that all Replication unit test should extend.
 */
@SuppressWarnings("javadoc")
@Test(groups = { "precommit", "replication" }, sequential = true)
public abstract class ReplicationTestCase extends DirectoryServerTestCase
{
  // The tracer object for the debug logger
  /** The tracer object for the debug logger */
  private static final DebugTracer TRACER = getTracer();
  // This is the generation id matching the memory test backend
  // with its initial root entry o=test created.
  // This matches the backend obtained calling:
  // TestCaseUtils.initializeTestBackend(true).
  // (using the default TestCaseUtils.TEST_ROOT_DN_STRING suffix)
  /**
   * This is the generation id matching the memory test backend with its initial
   * root entry o=test created. This matches the backend obtained calling:
   * TestCaseUtils.initializeTestBackend(true). (using the default
   * TestCaseUtils.TEST_ROOT_DN_STRING suffix)
   */
  protected static final long TEST_DN_WITH_ROOT_ENTRY_GENID = 5055L;
  /**
@@ -249,33 +251,6 @@
  }
  /**
   * Open an ECL replicationServer session to the local ReplicationServer
  protected ReplicationBroker openECLReplicationSession(
        int window_size, int port, int timeout, boolean emptyOldChanges,
        Short serverId)
  throws Exception, SocketException
  {
    ServerState state = new ServerState();
    //if (emptyOldChanges)
    //   new PersistentServerState(baseDn, serverId, new ServerState());
    ReplicationBroker broker = new ReplicationBroker(null,
        state, "cn=changelog", serverId, window_size,
        -1, 100000, getReplSessionSecurity(), (byte)1);
    ArrayList<String> servers = new ArrayList<String>(1);
    servers.add("localhost:" + port);
    broker.start(servers);
    if (timeout != 0)
      broker.setSoTimeout(timeout);
    checkConnection(30, broker, port); // give some time to the broker to connect
                                       // to the replicationServer.
    return broker;
  }
  */
  /**
   * Check connection of the provided ds to the
   * replication server. Waits for connection to be ok up to secTimeout seconds
   * before failing.
@@ -437,7 +412,6 @@
    logError(Message.raw(Category.SYNC, Severity.NOTICE,
    "ReplicationTestCase/Cleaning entries"));
    DeleteOperationBasis op;
    // Delete entries
    try
    {
@@ -564,7 +538,7 @@
      // Check that no entries have been found
      LinkedList<SearchResultEntry> entries = op.getSearchEntries();
      assertTrue(entries != null);
      assertNotNull(entries);
      StringBuilder sb = new StringBuilder();
      for (SearchResultEntry entry : entries)
      {
@@ -650,17 +624,7 @@
    do
    {
      Entry newEntry;
      Lock lock = null;
      for (int j=0; j < 3; j++)
      {
        lock = LockManager.lockRead(dn);
        if (lock != null)
        {
          break;
        }
      }
      final Lock lock = LockManager.lockRead(dn);
      if (lock == null)
      {
        throw new Exception("could not lock entry " + dn);
@@ -668,9 +632,7 @@
      try
      {
        newEntry = DirectoryServer.getEntry(dn);
        final Entry newEntry = DirectoryServer.getEntry(dn);
        if (newEntry != null)
        {
          List<Attribute> tmpAttrList = newEntry.getAttribute(attrTypeStr);
@@ -683,7 +645,6 @@
            found = tmpAttr.contains(AttributeValues.create(attrType, valueString));
          }
        }
      }
      finally
      {
@@ -715,16 +676,7 @@
      count--;
    }
    Lock lock = null;
    for (int i=0; i < 3; i++)
    {
      lock = LockManager.lockRead(dn);
      if (lock != null)
      {
        break;
      }
    }
    final Lock lock = LockManager.lockRead(dn);
    if (lock == null)
    {
      throw new Exception("could not lock entry " + dn);
@@ -773,7 +725,7 @@
      lastCount = currentCount;
    } catch (Exception ex) {
      ex.printStackTrace();
      assertTrue(false);
      fail();
    }
    return delta;
  }
@@ -848,10 +800,7 @@
      }
    } while (completionTime == null);
    if (completionTime == null)
    {
      fail("The task has not completed after 30 seconds.");
    }
    assertNotNull(completionTime, "The task has not completed after 30 seconds.");
    // Check that the task state is as expected.
    AttributeType taskStateType =
@@ -1091,16 +1040,7 @@
    {
      Thread.sleep(100);
      Lock lock = null;
      for (int i=0; i < 3; i++)
      {
        lock = LockManager.lockRead(dn);
        if (lock != null)
        {
          break;
        }
      }
      final Lock lock = LockManager.lockRead(dn);
      if (lock == null)
      {
        throw new Exception("could not lock entry " + dn);