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

Matthew Swift
27.31.2011 d57e8fd5ca53257eab611c2a592de8b57d086158
Fix OPENDJ-245: Improve APIs for adding additional access log items to operations
2 files added
17 files modified
959 ■■■■■ changed files
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/OperationWrapper.java 41 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandler.java 15 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java 12 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/WhoAmIExtendedOperation.java 6 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java 95 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java 39 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AbstractOperation.java 70 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AdditionalLogItem.java 245 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/Operation.java 36 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/InProgressOperation.java 66 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/PostOperationOperation.java 66 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/PostResponseOperation.java 26 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/PostSynchronizationOperation.java 26 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/PreOperationOperation.java 63 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/operation/PreParseOperation.java 38 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java 6 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/IsolationTest.java 8 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/types/AdditionalLogItemTest.java 96 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -2057,8 +2057,9 @@
      if(isSubtreeDelete)
      {
        deleteOperation.appendAdditionalLogMessage(
            NOTE_JEB_DELETED_ENTRY_COUNT.get(subordinateEntriesDeleted + 1));
        deleteOperation.addAdditionalLogItem(AdditionalLogItem
            .unquotedKeyValue(getClass(), "deletedEntries",
                subordinateEntriesDeleted + 1));
      }
    }
    catch (DatabaseException databaseException)
opends/src/server/org/opends/server/core/OperationWrapper.java
@@ -77,14 +77,6 @@
  /**
   * {@inheritDoc}
   */
  public void appendAdditionalLogMessage(Message message)
  {
    operation.appendAdditionalLogMessage(message);
  }
  /**
   * {@inheritDoc}
   */
  public void appendErrorMessage(Message message)
  {
    operation.appendErrorMessage(message);
@@ -130,14 +122,6 @@
  /**
   * {@inheritDoc}
   */
  public MessageBuilder getAdditionalLogMessage()
  {
    return operation.getAdditionalLogMessage();
  }
  /**
   * {@inheritDoc}
   */
  public Object getAttachment(String name)
  {
    return operation.getAttachment(name);
@@ -387,14 +371,6 @@
  /**
   * {@inheritDoc}
   */
  public void setAdditionalLogMessage(MessageBuilder additionalLogMessage)
  {
    operation.setAdditionalLogMessage(additionalLogMessage);
  }
  /**
   * {@inheritDoc}
   */
  public Object setAttachment(String name, Object value)
  {
    return operation.setAttachment(name, value);
@@ -539,5 +515,22 @@
  {
    operation.registerPostResponseCallback(callback);
  }
  /**
   * {@inheritDoc}
   */
  public List<AdditionalLogItem> getAdditionalLogItems()
  {
    return operation.getAdditionalLogItems();
  }
  /**
   *{@inheritDoc}
   */
  public void addAdditionalLogItem(AdditionalLogItem item)
  {
    operation.addAdditionalLogItem(item);
  }
}
opends/src/server/org/opends/server/extensions/AnonymousSASLMechanismHandler.java
@@ -23,21 +23,18 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.server.extensions;
import org.opends.messages.MessageBuilder;
import org.opends.server.admin.std.server.AnonymousSASLMechanismHandlerCfg;
import org.opends.server.api.SASLMechanismHandler;
import org.opends.server.config.ConfigException;
import org.opends.server.core.BindOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
@@ -111,12 +108,8 @@
      String credString = saslCredentials.toString();
      if (credString.length() > 0)
      {
        MessageBuilder mb = new MessageBuilder();
        mb.append("trace='");
        mb.append(credString);
        mb.append("'");
        bindOperation.appendAdditionalLogMessage(mb.toMessage());
        bindOperation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue(
            getClass(), "trace", credString));
        logError(INFO_SASLANONYMOUS_TRACE.
            get(bindOperation.getConnectionID(), bindOperation.getOperationID(),
                credString));
opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -639,9 +639,9 @@
            (! operation.getClientConnection().isSecure()))
        {
          operation.setResultCode(ResultCode.CONFIDENTIALITY_REQUIRED);
          operation.appendAdditionalLogMessage(
                  ERR_EXTOP_PASSMOD_SECURE_AUTH_REQUIRED.get());
          operation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue(
              getClass(), "additionalInfo",
              ERR_EXTOP_PASSMOD_SECURE_AUTH_REQUIRED.get()));
          return;
        }
@@ -652,9 +652,9 @@
        else
        {
          operation.setResultCode(ResultCode.INVALID_CREDENTIALS);
          operation.appendAdditionalLogMessage(
                  ERR_EXTOP_PASSMOD_INVALID_OLD_PASSWORD.get());
          operation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue(
              getClass(), "additionalInfo",
              ERR_EXTOP_PASSMOD_INVALID_OLD_PASSWORD.get()));
          pwPolicyState.updateAuthFailureTimes();
          List<Modification> mods = pwPolicyState.getModifications();
opends/src/server/org/opends/server/extensions/WhoAmIExtendedOperation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -31,7 +32,6 @@
import java.util.HashSet;
import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.WhoAmIExtendedOperationHandlerCfg;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ExtendedOperationHandler;
@@ -200,8 +200,8 @@
    }
    operation.setResponseValue(ByteString.valueOf(authzID));
    operation.appendAdditionalLogMessage(
            Message.raw("authzID=\"" + authzID + "\""));
    operation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue(
        getClass(), "authzID", authzID));
    operation.setResultCode(ResultCode.SUCCESS);
  }
opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java
@@ -60,16 +60,7 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.core.UnbindOperation;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DisconnectReason;
import org.opends.server.types.FilePermission;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Operation;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import org.opends.server.util.TimeThread;
@@ -485,13 +476,7 @@
      buffer.append('\"');
    }
    msg = abandonOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(abandonOperation, buffer);
    buffer.append(" etime=");
    buffer.append(abandonOperation.getProcessingTime());
@@ -571,13 +556,7 @@
      buffer.append('\"');
    }
    msg = addOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(addOperation, buffer);
    DN proxiedAuthDN = addOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -703,13 +682,7 @@
      buffer.append('\"');
    }
    msg = bindOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(bindOperation, buffer);
    if (bindOperation.getResultCode() == ResultCode.SUCCESS)
    {
@@ -825,13 +798,7 @@
      buffer.append('\"');
    }
    msg = compareOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(compareOperation, buffer);
    DN proxiedAuthDN = compareOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -974,13 +941,7 @@
      buffer.append('\"');
    }
    msg = deleteOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(deleteOperation, buffer);
    DN proxiedAuthDN = deleteOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -1166,13 +1127,7 @@
      buffer.append('\"');
    }
    msg = extendedOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(extendedOperation, buffer);
    buffer.append(" etime=");
    long etime = extendedOperation.getProcessingNanoTime();
@@ -1270,13 +1225,7 @@
      buffer.append('\"');
    }
    msg = modifyDNOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(modifyDNOperation, buffer);
    DN proxiedAuthDN = modifyDNOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -1369,13 +1318,7 @@
      buffer.append('\"');
    }
    msg = modifyOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(modifyOperation, buffer);
    DN proxiedAuthDN = modifyOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -1494,13 +1437,7 @@
    buffer.append(" nentries=");
    buffer.append(searchOperation.getEntriesSent());
    msg = searchOperation.getAdditionalLogMessage();
    if ((msg != null) && (msg.length() > 0))
    {
      buffer.append(" additionalInfo=\"");
      buffer.append(msg);
      buffer.append('\"');
    }
    logAdditionalLogItems(searchOperation, buffer);
    DN proxiedAuthDN = searchOperation.getProxiedAuthorizationDN();
    if (proxiedAuthDN != null)
@@ -1596,6 +1533,18 @@
  // Appends additional log items to the provided builder.
  private void logAdditionalLogItems(Operation operation, StringBuilder builder)
  {
    for (AdditionalLogItem item : operation.getAdditionalLogItems())
    {
      builder.append(' ');
      item.toString(builder);
    }
  }
  // Writes an intermediate message to the log.
  private void logIntermediateMessage(Operation operation, String opType,
      String category, Map<String, String> content)
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -108,39 +108,7 @@
import org.opends.server.replication.service.ReplicationDomain;
import org.opends.server.replication.service.ReplicationMonitor;
import org.opends.server.tasks.TaskUtils;
import org.opends.server.types.AbstractOperation;
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.Attributes;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConfigChangeResult;
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.ExistingFileBehavior;
import org.opends.server.types.LDAPException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.Operation;
import org.opends.server.types.OperationType;
import org.opends.server.types.RDN;
import org.opends.server.types.RawModification;
import org.opends.server.types.ResultCode;
import org.opends.server.types.Schema;
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.SynchronizationProviderResult;
import org.opends.server.types.*;
import org.opends.server.types.operation.PluginOperation;
import org.opends.server.types.operation.PostOperationAddOperation;
import org.opends.server.types.operation.PostOperationDeleteOperation;
@@ -2324,9 +2292,8 @@
    ChangeNumber curChangeNumber = OperationContext.getChangeNumber(op);
    if ((curChangeNumber != null) && (logChangeNumber))
    {
      Message message =
        Message.raw("replicationCN:%s", curChangeNumber.toString());
      op.appendAdditionalLogMessage(message);
      op.addAdditionalLogItem(AdditionalLogItem.unquotedKeyValue(getClass(),
          "replicationCN", curChangeNumber));
    }
    if ((result == ResultCode.SUCCESS) && (!op.isSynchronizationOperation()))
opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -32,14 +32,12 @@
import static org.opends.server.core.CoreConstants.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.opends.server.api.ClientConnection;
import org.opends.server.types.operation.PostResponseOperation;
import org.opends.server.types.operation.PreParseOperation;
import org.opends.server.util.Validator;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.loggers.debug.
@@ -147,7 +145,7 @@
  // Additional information that should be included in the log but
  // not sent to the client.
  private MessageBuilder additionalLogMessage;
  private List<AdditionalLogItem> additionalLogItems;
  // The error message for this operation that should be included in
  // the log and in the response to the client.
@@ -207,7 +205,7 @@
    }
    resultCode                 = ResultCode.UNDEFINED;
    additionalLogMessage       = null;
    additionalLogItems         = null;
    errorMessage               = new MessageBuilder();
    attachments                = new HashMap<String,Object>();
    matchedDN                  = null;
@@ -565,64 +563,33 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by
   * pre-parse, pre-operation, and post-operation plugins, but not by
   * post-response plugins.
   *
   * @return  The additional log message for this operation.
   * {@inheritDoc}
   */
  public final MessageBuilder getAdditionalLogMessage()
  public List<AdditionalLogItem> getAdditionalLogItems()
  {
    return additionalLogMessage;
  }
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  This method may not be called by post-response
   * plugins.
   *
   * @param  additionalLogMessage  The additional log message for this
   *                               operation.
   */
  public final void setAdditionalLogMessage(
                         MessageBuilder additionalLogMessage)
  {
    if (additionalLogMessage == null)
    if (additionalLogItems == null)
    {
      this.additionalLogMessage = new MessageBuilder();
      return Collections.emptyList();
    }
    else
    {
      this.additionalLogMessage = additionalLogMessage;
      return Collections.unmodifiableList(additionalLogItems);
    }
  }
  /**
   * Appends the provided message to the additional log information
   * for this operation.  This method may not be called by
   * post-response plugins.
   *
   * @param  message  The message that should be appended to the
   *                  additional log information for this operation.
   * {@inheritDoc}
   */
  public final void appendAdditionalLogMessage(Message message)
  public void addAdditionalLogItem(AdditionalLogItem item)
  {
    if (additionalLogMessage == null)
    Validator.ensureNotNull(item);
    if (additionalLogItems == null)
    {
      additionalLogMessage = new MessageBuilder(message);
      additionalLogItems = new LinkedList<AdditionalLogItem>();
    }
    else
    {
      additionalLogMessage.append(" ");
      additionalLogMessage.append(message);
    }
    additionalLogItems.add(item);
  }
@@ -630,9 +597,8 @@
  /**
   * Retrieves the matched DN for this operation.
   *
   * @return  The matched DN for this operation, or {@code null} if
   *          the operation has not yet completed or does not have a
   *          matched DN.
   * @return The matched DN for this operation, or {@code null} if the operation
   *         has not yet completed or does not have a matched DN.
   */
  public final DN getMatchedDN()
  {
opends/src/server/org/opends/server/types/AdditionalLogItem.java
New file
@@ -0,0 +1,245 @@
/*
 * 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
 *
 *
 *      Copyright 2011 ForgeRock AS
 */
package org.opends.server.types;
import org.opends.server.util.Validator;
/**
 * An additional log item for an operation which may be processed in the access
 * log.
 * <p>
 * Log items comprise of a source class, a key, and an optional value. If no
 * value is present then only the key will be displayed in the log, otherwise
 * both the key and value will usually be displayed using the format
 * {@code key=value}. Log item values are {@code Object} instances whose string
 * representation will be derived using the object's {@code toString()} method.
 * <p>
 * Log implementations may use the source class and/or key in order to filter
 * out unwanted log items.
 */
public final class AdditionalLogItem
{
  /**
   * Creates a new additional log item using the provided source and key, but no
   * value.
   *
   * @param source
   *          The class which generated the additional log item.
   * @param key
   *          The log item key.
   * @return The new additional log item.
   */
  public static AdditionalLogItem keyOnly(final Class<?> source,
      final String key)
  {
    Validator.ensureNotNull(source, key);
    return new AdditionalLogItem(source, key, null, false);
  }
  /**
   * Creates a new additional log item using the provided source, key, and
   * value. The value will be surrounded by quotes when serialized as a string.
   *
   * @param source
   *          The class which generated the additional log item.
   * @param key
   *          The log item key.
   * @param value
   *          The log item value.
   * @return The new additional log item.
   */
  public static AdditionalLogItem quotedKeyValue(final Class<?> source,
      final String key, final Object value)
  {
    Validator.ensureNotNull(source, key, value);
    return new AdditionalLogItem(source, key, value, true);
  }
  /**
   * Creates a new additional log item using the provided source, key, and
   * value. The value will not be surrounded by quotes when serialized as a
   * string.
   *
   * @param source
   *          The class which generated the additional log item.
   * @param key
   *          The log item key.
   * @param value
   *          The log item value.
   * @return The new additional log item.
   */
  public static AdditionalLogItem unquotedKeyValue(final Class<?> source,
      final String key, final Object value)
  {
    Validator.ensureNotNull(source, key, value);
    return new AdditionalLogItem(source, key, value, false);
  }
  private final Class<?> source;
  private final String key;
  private final Object value;
  private final boolean isQuoted;
  /**
   * Creates a new additional log item.
   *
   * @param source
   *          The class which generated the additional log item.
   * @param key
   *          The log item key.
   * @param value
   *          The log item value.
   * @param isQuoted
   *          {@code true} if this item's value should be surrounded by quotes
   *          during serialization.
   */
  private AdditionalLogItem(final Class<?> source, final String key,
      final Object value, final boolean isQuoted)
  {
    this.source = source;
    this.key = key;
    this.value = value;
    this.isQuoted = isQuoted;
  }
  /**
   * Returns the log item key.
   *
   * @return The log item key.
   */
  public String getKey()
  {
    return key;
  }
  /**
   * Returns the class which generated the additional log item.
   *
   * @return The class which generated the additional log item.
   */
  public Class<?> getSource()
  {
    return source;
  }
  /**
   * Returns the log item value, or {@code null} if this log item does not have
   * a value.
   *
   * @return The log item value, or {@code null} if this log item does not have
   *         a value.
   */
  public Object getValue()
  {
    return value;
  }
  /**
   * Returns {@code true} if this item's value should be surrounded by quotes
   * during serialization.
   *
   * @return {@code true} if this item's value should be surrounded by quotes
   *         during serialization.
   */
  public boolean isQuoted()
  {
    return isQuoted;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    if (value == null)
    {
      return key;
    }
    else
    {
      final StringBuilder builder = new StringBuilder(key.length() + 16);
      toString(builder);
      return builder.toString();
    }
  }
  /**
   * Appends the string representation of this additional log item to the
   * provided string builder.
   *
   * @param builder
   *          The string builder.
   * @return A reference to the updated string builder.
   */
  public StringBuilder toString(final StringBuilder builder)
  {
    builder.append(key);
    if (value != null)
    {
      builder.append('=');
      if (isQuoted)
      {
        builder.append('\'');
      }
      builder.append(value.toString());
      if (isQuoted)
      {
        builder.append('\'');
      }
    }
    return builder;
  }
}
opends/src/server/org/opends/server/types/Operation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types;
import org.opends.messages.Message;
@@ -278,35 +279,24 @@
  public abstract void appendErrorMessage(Message message);
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by
   * pre-parse, pre-operation, and post-operation plugins, but not by
   * post-response plugins.
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return  The additional log message for this operation.
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public abstract MessageBuilder getAdditionalLogMessage();
  public abstract List<AdditionalLogItem> getAdditionalLogItems();
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  This method may not be called by post-response
   * plugins.
   * Adds an additional log item to this operation, which should be written to
   * the log but not included in the response to the client. This method may not
   * be called by post-response plugins.
   *
   * @param  additionalLogMessage  The additional log message for this
   * @param item
   *          The additional log item for this operation.
   */
  public abstract void setAdditionalLogMessage(
      MessageBuilder additionalLogMessage);
  /**
   * Appends the provided message to the additional log information
   * for this operation.  This method may not be called by
   * post-response plugins.
   *
   * @param  message  The message that should be appended to the
   */
  public abstract void appendAdditionalLogMessage(Message message);
  public abstract void addAdditionalLogItem(AdditionalLogItem item);
  /**
   * Retrieves the matched DN for this operation.
opends/src/server/org/opends/server/types/operation/InProgressOperation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import org.opends.messages.Message;
@@ -31,10 +32,7 @@
import java.util.List;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import org.opends.messages.MessageBuilder;
@@ -128,42 +126,6 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   *
   * @return  The additional log message for this operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.
   *
   * @param  additionalLogMessage  The additional log message for this
   *                               operation.
   */
  public void setAdditionalLogMessage(
                   MessageBuilder additionalLogMessage);
  /**
   * Appends the provided message to the additional log information
   * for this operation.
   *
   * @param  message  The message that should be appended to the
   *                  additional log information for this operation.
   */
  public void appendAdditionalLogMessage(Message message);
  /**
   * Retrieves the matched DN for this operation.
   *
   * @return  The matched DN for this operation, or <CODE>null</CODE>
@@ -230,5 +192,29 @@
   * @return  The authorization DN for this operation.
   */
  public DN getAuthorizationDN();
  /**
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public List<AdditionalLogItem> getAdditionalLogItems();
  /**
   * Adds an additional log item to this operation, which should be written to
   * the log but not included in the response to the client. This method may not
   * be called by post-response plugins.
   *
   * @param item
   *          The additional log item for this operation.
   */
  public void addAdditionalLogItem(AdditionalLogItem item);
}
opends/src/server/org/opends/server/types/operation/PostOperationOperation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import org.opends.messages.Message;
@@ -31,10 +32,7 @@
import java.util.List;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.*;
import org.opends.messages.MessageBuilder;
@@ -126,42 +124,6 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   *
   * @return  The additional log message for this operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.
   *
   * @param  additionalLogMessage  The additional log message for this
   *                               operation.
   */
  public void setAdditionalLogMessage(
                   MessageBuilder additionalLogMessage);
  /**
   * Appends the provided message to the additional log information
   * for this operation.
   *
   * @param  message  The message that should be appended to the
   *                  additional log information for this operation.
   */
  public void appendAdditionalLogMessage(Message message);
  /**
   * Retrieves the matched DN for this operation.
   *
   * @return  The matched DN for this operation, or <CODE>null</CODE>
@@ -228,5 +190,29 @@
   * @return  The authorization DN for this operation.
   */
  public DN getAuthorizationDN();
  /**
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public List<AdditionalLogItem> getAdditionalLogItems();
  /**
   * Adds an additional log item to this operation, which should be written to
   * the log but not included in the response to the client. This method may not
   * be called by post-response plugins.
   *
   * @param item
   *          The additional log item for this operation.
   */
  public void addAdditionalLogItem(AdditionalLogItem item);
}
opends/src/server/org/opends/server/types/operation/PostResponseOperation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import org.opends.messages.MessageBuilder;
@@ -30,6 +31,7 @@
import java.util.List;
import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.DN;
import org.opends.server.types.ResultCode;
@@ -71,18 +73,6 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   *
   * @return  The additional log message for this operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  /**
   * Retrieves the matched DN for this operation.
   *
   * @return  The matched DN for this operation, or <CODE>null</CODE>
@@ -139,5 +129,17 @@
   *          processing this operation.
   */
  public long getProcessingTime();
  /**
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public List<AdditionalLogItem> getAdditionalLogItems();
}
opends/src/server/org/opends/server/types/operation/PostSynchronizationOperation.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import org.opends.messages.MessageBuilder;
@@ -30,6 +31,7 @@
import java.util.List;
import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.DN;
import org.opends.server.types.ResultCode;
@@ -72,18 +74,6 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   *
   * @return  The additional log message for this operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  /**
   * Retrieves the matched DN for this operation.
   *
   * @return  The matched DN for this operation, or <CODE>null</CODE>
@@ -140,5 +130,17 @@
   *          processing this operation.
   */
  public long getProcessingTime();
  /**
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public List<AdditionalLogItem> getAdditionalLogItems();
}
opends/src/server/org/opends/server/types/operation/PreOperationOperation.java
@@ -23,11 +23,15 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import java.util.List;
import org.opends.messages.Message;
import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
@@ -102,41 +106,6 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   *
   * @return  The additional log message for this operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.
   *
   * @param  additionalLogMessage  The additional log message for this
   */
  public void setAdditionalLogMessage(
                   MessageBuilder additionalLogMessage);
  /**
   * Appends the provided message to the additional log information
   * for this operation.
   *
   * @param  message  The message that should be appended to the
   *                  additional log information for this operation.
   */
  public void appendAdditionalLogMessage(Message message);
  /**
   * Retrieves the authorization DN for this operation.  In many
   * cases, it will be the same as the DN of the authenticated user
   * for the underlying connection, or the null DN if no
@@ -148,5 +117,29 @@
   * @return  The authorization DN for this operation.
   */
  public DN getAuthorizationDN();
  /**
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public List<AdditionalLogItem> getAdditionalLogItems();
  /**
   * Adds an additional log item to this operation, which should be written to
   * the log but not included in the response to the client. This method may not
   * be called by post-response plugins.
   *
   * @param item
   *          The additional log item for this operation.
   */
  public void addAdditionalLogItem(AdditionalLogItem item);
}
opends/src/server/org/opends/server/types/operation/PreParseOperation.java
@@ -23,8 +23,11 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 */
package org.opends.server.types.operation;
import java.util.List;
import org.opends.messages.Message;
@@ -124,36 +127,25 @@
  /**
   * Retrieves the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.  The contents of this buffer may be altered by the
   * caller.
   * Returns an unmodifiable list containing the additional log items for this
   * operation, which should be written to the log but not included in the
   * response to the client.
   *
   * @return  The additional log message for this operation.
   * @return An unmodifiable list containing the additional log items for this
   *         operation.
   */
  public MessageBuilder getAdditionalLogMessage();
  public List<AdditionalLogItem> getAdditionalLogItems();
  /**
   * Specifies the additional log message for this operation, which
   * should be written to the log but not included in the response to
   * the client.
   * Adds an additional log item to this operation, which should be written to
   * the log but not included in the response to the client. This method may not
   * be called by post-response plugins.
   *
   * @param  additionalLogMessage  The additional log message for this
   * @param item
   *          The additional log item for this operation.
   */
  public void setAdditionalLogMessage(
                   MessageBuilder additionalLogMessage);
  /**
   * Appends the provided message to the additional log information
   * for this operation.
   *
   * @param  message  The message that should be appended to the
   *                  additional log information for this operation.
   */
  public void appendAdditionalLogMessage(Message message);
  public void addAdditionalLogItem(AdditionalLogItem item);
}
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java
@@ -558,10 +558,10 @@
  protected void removeReplicationServerDB() {
    for (ReplicationServer rs : ReplicationServer.getAllInstances()) {
      StaticUtils.recursiveDelete(new File(DirectoryServer.getInstanceRoot(),
               rs.getDbDirName()));
               rs.getDbDirName()));
    }
  }
  /**
   * Performs a search on the config backend with the specified filter.
   * Fails if a config entry is found.
@@ -927,7 +927,7 @@
          + addOperation.getResultCode()
          + " Expected:"
          + expectedResult + " Details:" + addOperation.getErrorMessage()
          + addOperation.getAdditionalLogMessage());
          + addOperation.getAdditionalLogItems());
      if (expectedResult != ResultCode.SUCCESS)
      {
opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/IsolationTest.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.server.replication.plugin;
@@ -35,8 +36,6 @@
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.IsolationPolicy;
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.replication.ReplicationTestCase;
@@ -55,8 +54,9 @@
   * Check that the server correctly accept or reject updates when
   * the replication is configured but could not connect to
   * any of the configured replication server.
   *
   * @throws Exception If an unexpected error occurred.
   */
  @SuppressWarnings("unchecked")
  @Test()
  public void noUpdateIsolationPolicyTest() throws Exception
  {
@@ -100,7 +100,7 @@
      // check that the operation was successful.
      assertEquals(op.getResultCode(), ResultCode.SUCCESS,
          op.getAdditionalLogMessage().toString());
          op.getAdditionalLogItems().toString());
    }
    finally
    {
opends/tests/unit-tests-testng/src/server/org/opends/server/types/AdditionalLogItemTest.java
New file
@@ -0,0 +1,96 @@
/*
 * 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
 *
 *
 *      Copyright 2011 ForgeRock AS
 */
package org.opends.server.types;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
/**
 * Tests for {@link AdditionalLogItem}.
 */
public class AdditionalLogItemTest extends TypesTestCase
{
  /**
   * Tests {@link AdditionalLogItem#keyOnly(Class, String)}.
   */
  @Test
  public void testKeyOnly()
  {
    AdditionalLogItem item = AdditionalLogItem.keyOnly(getClass(), "testKey");
    assertEquals(item.getSource(), getClass());
    assertEquals(item.getKey(), "testKey");
    assertEquals(item.getValue(), null);
    assertEquals(item.toString(), "testKey");
    assertEquals(item.toString(new StringBuilder()).toString(), "testKey");
  }
  /**
   * Tests {@link AdditionalLogItem#quotedKeyValue(Class, String, Object)}.
   */
  @Test
  public void testQuotedKeyValue()
  {
    AdditionalLogItem item = AdditionalLogItem.quotedKeyValue(getClass(),
        "testKey", "testValue");
    assertEquals(item.getSource(), getClass());
    assertEquals(item.getKey(), "testKey");
    assertEquals(item.getValue(), "testValue");
    assertTrue(item.isQuoted());
    assertEquals(item.toString(), "testKey='testValue'");
    assertEquals(item.toString(new StringBuilder()).toString(),
        "testKey='testValue'");
  }
  /**
   * Tests {@link AdditionalLogItem#unquotedKeyValue(Class, String, Object)}.
   */
  @Test
  public void testUnquotedKeyValue()
  {
    AdditionalLogItem item = AdditionalLogItem.unquotedKeyValue(getClass(),
        "testKey", "testValue");
    assertEquals(item.getSource(), getClass());
    assertEquals(item.getKey(), "testKey");
    assertEquals(item.getValue(), "testValue");
    assertFalse(item.isQuoted());
    assertEquals(item.toString(), "testKey=testValue");
    assertEquals(item.toString(new StringBuilder()).toString(),
        "testKey=testValue");
  }
}