From e4e9b2ebc7d41715fc0c0c8ba07f897fe63a688e Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 16 Jan 2008 23:19:50 +0000
Subject: [PATCH] This fix removes the option to use nanosecond etime resolution as a JVM property. It is now a global configuration attribute. Due to the 10% throughput decrease I saw when using System.nanoTime, the default still uses System.currentTimeMillis to timestamp operations. System.nanoTime will only be used when the ds-cfg-etime-resolution attribute is set to nano-seconds.

---
 opends/resource/schema/02-config.ldif                                     |    8 
 opends/src/server/org/opends/server/core/SearchOperationBasis.java        |   16 
 opends/src/server/org/opends/server/util/TimeThread.java                  |   19 +
 opends/src/server/org/opends/server/types/AbstractOperation.java          |   63 ++++-
 opends/resource/config/config.ldif                                        |    1 
 opends/src/server/org/opends/server/loggers/AccessLogger.java             |  415 ++++++++++++++++++++--------------------
 opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml |   32 +++
 opends/src/server/org/opends/server/core/CoreConfigManager.java           |   12 
 opends/src/server/org/opends/server/util/ServerConstants.java             |   10 
 9 files changed, 326 insertions(+), 250 deletions(-)

diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 8e6d921..3548cd4 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -49,6 +49,7 @@
 ds-cfg-return-bind-error-messages: false
 ds-cfg-idle-time-limit: 0 seconds
 ds-cfg-save-config-on-successful-startup: true
+ds-cfg-etime-resolution: milli-seconds
 ds-cfg-allowed-task: org.opends.server.tasks.AddSchemaFileTask
 ds-cfg-allowed-task: org.opends.server.tasks.BackupTask
 ds-cfg-allowed-task: org.opends.server.tasks.DisconnectClientTask
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index a88fbdf..e818a99 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2172,6 +2172,11 @@
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
   SINGLE-VALUE
   X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.442
+  NAME 'ds-cfg-etime-resolution'
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  SINGLE-VALUE
+  X-ORIGIN 'OpenDS Directory Server' )
 attributeTypes: ( 1.3.6.1.4.1.26027.1.1.444
   NAME 'ds-task-reset-generation-id-new-value'
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
@@ -2582,7 +2587,8 @@
         ds-cfg-return-bind-error-messages $
         ds-cfg-idle-time-limit $
         ds-cfg-workflow-configuration-mode $
-        ds-cfg-save-config-on-successful-startup )
+        ds-cfg-save-config-on-successful-startup $
+        ds-cfg-etime-resolution )
   X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.40
   NAME 'ds-cfg-root-dn-user'
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
index a082507..3a5f55f 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -778,4 +778,36 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
+  <adm:property name="etime-resolution" mandatory="false">
+    <adm:synopsis>
+      The resolution to use for operation elapsed processing time (etime)
+      measurements.
+    </adm:synopsis>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>
+          milli-seconds
+        </adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:enumeration>
+        <adm:value name="milli-seconds">
+          <adm:synopsis>
+            Use milli-second resolution.
+          </adm:synopsis>
+        </adm:value>
+        <adm:value name="nano-seconds">
+          <adm:synopsis>
+            Use nano-second resolution.
+          </adm:synopsis>
+        </adm:value>
+      </adm:enumeration>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-etime-resolution</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
 </adm:managed-object>
diff --git a/opends/src/server/org/opends/server/core/CoreConfigManager.java b/opends/src/server/org/opends/server/core/CoreConfigManager.java
index f9fa411..8d5ca58 100644
--- a/opends/src/server/org/opends/server/core/CoreConfigManager.java
+++ b/opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 import org.opends.messages.Message;
@@ -42,12 +42,7 @@
 import org.opends.server.admin.std.server.RootCfg;
 import org.opends.server.admin.server.ServerManagementContext;
 import org.opends.server.config.ConfigException;
-import org.opends.server.types.AcceptRejectWarn;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.Privilege;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.WritabilityMode;
+import org.opends.server.types.*;
 
 import static org.opends.messages.ConfigMessages.*;
 
@@ -357,6 +352,9 @@
     {
       DirectoryServer.setWorkflowConfigurationMode(newMode);
     }
+
+    AbstractOperation.setUseNanoTime(globalConfig.getEtimeResolution() ==
+      GlobalCfgDefn.EtimeResolution.NANO_SECONDS);
   }
 
 
diff --git a/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index b3244ac..927fa69 100644
--- a/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 
@@ -627,8 +627,9 @@
 
     // See if the time limit has expired.  If so, then don't send the entry and
     // indicate that the search should end.
-    if ((getTimeLimit() > 0) && (TimeThread.getTime() >=
-                                                getTimeLimitExpiration()))
+    if ((getTimeLimit() > 0) &&
+        ((getUseNanoTime() ? TimeThread.getNanoTime() :
+                             TimeThread.getTime()) >= getTimeLimitExpiration()))
     {
       setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
       appendErrorMessage(ERR_SEARCH_TIME_LIMIT_EXCEEDED.get(getTimeLimit()));
@@ -1054,8 +1055,9 @@
 
     // See if the time limit has expired.  If so, then don't send the entry and
     // indicate that the search should end.
-    if ((getTimeLimit() > 0) && (TimeThread.getTime() >=
-                                        getTimeLimitExpiration()))
+    if ((getTimeLimit() > 0) &&
+        ((getUseNanoTime() ? TimeThread.getNanoTime() :
+                             TimeThread.getTime()) >= getTimeLimitExpiration()))
     {
       setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
       appendErrorMessage(ERR_SEARCH_TIME_LIMIT_EXCEEDED.get(getTimeLimit()));
@@ -1623,8 +1625,8 @@
     else
     {
       // FIXME -- Factor in the user's effective time limit.
-      timeLimitExpiration =
-        getProcessingStartTime() + (1000L * timeLimit);
+      timeLimitExpiration = getProcessingStartTime() +
+          ((getUseNanoTime() ? 1000000000L : 1000L) * timeLimit);
     }
     setTimeLimitExpiration(timeLimitExpiration);
 
diff --git a/opends/src/server/org/opends/server/loggers/AccessLogger.java b/opends/src/server/org/opends/server/loggers/AccessLogger.java
index d6e86c2..4e055ad 100644
--- a/opends/src/server/org/opends/server/loggers/AccessLogger.java
+++ b/opends/src/server/org/opends/server/loggers/AccessLogger.java
@@ -71,23 +71,24 @@
   private static final DebugTracer TRACER = getTracer();
 
   // The set of access loggers that have been registered with the server.  It
-   // will initially be empty.
-   static CopyOnWriteArrayList<AccessLogPublisher> accessPublishers =
-       new CopyOnWriteArrayList<AccessLogPublisher>();
+  // will initially be empty.
+  static CopyOnWriteArrayList<AccessLogPublisher> accessPublishers =
+      new CopyOnWriteArrayList<AccessLogPublisher>();
 
-   // The singleton instance of this class for configuration purposes.
-   static final AccessLogger instance = new AccessLogger();
+  // The singleton instance of this class for configuration purposes.
+  static final AccessLogger instance = new AccessLogger();
 
 
-   /**
-    * Retrieve the singleton instance of this class.
-    *
-    * @return The singleton instance of this logger.
-    */
-   public static AccessLogger getInstance()
-   {
-     return instance;
-   }
+
+  /**
+   * Retrieve the singleton instance of this class.
+   *
+   * @return The singleton instance of this logger.
+   */
+  public static AccessLogger getInstance()
+  {
+    return instance;
+  }
 
   /**
    * Add an access log publisher to the access logger.
@@ -144,101 +145,101 @@
    *           If a problem occurs during initialization that is not
    *           related to the server configuration.
    */
-   public void initializeAccessLogger(List<AccessLogPublisherCfg> configs)
-       throws ConfigException, InitializationException
-   {
-     for(AccessLogPublisherCfg config : configs)
-     {
-       config.addAccessChangeListener(this);
+  public void initializeAccessLogger(List<AccessLogPublisherCfg> configs)
+      throws ConfigException, InitializationException
+  {
+    for(AccessLogPublisherCfg config : configs)
+    {
+      config.addAccessChangeListener(this);
 
-       if(config.isEnabled())
-       {
-         AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
+      if(config.isEnabled())
+      {
+        AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
 
-         addAccessLogPublisher(AccessLogPublisher);
-       }
-     }
-   }
+        addAccessLogPublisher(AccessLogPublisher);
+      }
+    }
+  }
 
   /**
    * {@inheritDoc}
    */
-   public boolean isConfigurationAddAcceptable(
-          AccessLogPublisherCfg config,
-          List<Message> unacceptableReasons)
-   {
-     return !config.isEnabled() ||
-         isJavaClassAcceptable(config, unacceptableReasons);
-   }
+  public boolean isConfigurationAddAcceptable(
+      AccessLogPublisherCfg config,
+      List<Message> unacceptableReasons)
+  {
+    return !config.isEnabled() ||
+        isJavaClassAcceptable(config, unacceptableReasons);
+  }
 
   /**
    * {@inheritDoc}
    */
-   public boolean isConfigurationChangeAcceptable(
-          AccessLogPublisherCfg config,
-          List<Message> unacceptableReasons)
-   {
-     return !config.isEnabled() ||
-         isJavaClassAcceptable(config, unacceptableReasons);
-   }
+  public boolean isConfigurationChangeAcceptable(
+      AccessLogPublisherCfg config,
+      List<Message> unacceptableReasons)
+  {
+    return !config.isEnabled() ||
+        isJavaClassAcceptable(config, unacceptableReasons);
+  }
 
   /**
    * {@inheritDoc}
    */
-   public ConfigChangeResult applyConfigurationAdd(AccessLogPublisherCfg config)
-   {
-     // Default result code.
-     ResultCode resultCode = ResultCode.SUCCESS;
-     boolean adminActionRequired = false;
-     ArrayList<Message> messages = new ArrayList<Message>();
+  public ConfigChangeResult applyConfigurationAdd(AccessLogPublisherCfg config)
+  {
+    // Default result code.
+    ResultCode resultCode = ResultCode.SUCCESS;
+    boolean adminActionRequired = false;
+    ArrayList<Message> messages = new ArrayList<Message>();
 
-     config.addAccessChangeListener(this);
+    config.addAccessChangeListener(this);
 
-     if(config.isEnabled())
-     {
-       try
-       {
-         AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
+    if(config.isEnabled())
+    {
+      try
+      {
+        AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
 
-         addAccessLogPublisher(AccessLogPublisher);
-       }
-       catch(ConfigException e)
-       {
-         if (debugEnabled())
-         {
-           TRACER.debugCaught(DebugLogLevel.ERROR, e);
-         }
-         messages.add(e.getMessageObject());
-         resultCode = DirectoryServer.getServerErrorResultCode();
-       }
-       catch (Exception e)
-       {
-         if (debugEnabled())
-         {
-           TRACER.debugCaught(DebugLogLevel.ERROR, e);
-         }
+        addAccessLogPublisher(AccessLogPublisher);
+      }
+      catch(ConfigException e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+        messages.add(e.getMessageObject());
+        resultCode = DirectoryServer.getServerErrorResultCode();
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
 
-         messages.add(ERR_CONFIG_LOGGER_CANNOT_CREATE_LOGGER.get(
-                 String.valueOf(config.dn().toString()),
-                 stackTraceToSingleLineString(e)));
-         resultCode = DirectoryServer.getServerErrorResultCode();
-       }
-     }
-     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-   }
+        messages.add(ERR_CONFIG_LOGGER_CANNOT_CREATE_LOGGER.get(
+            String.valueOf(config.dn().toString()),
+            stackTraceToSingleLineString(e)));
+        resultCode = DirectoryServer.getServerErrorResultCode();
+      }
+    }
+    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+  }
 
   /**
    * {@inheritDoc}
    */
-   public ConfigChangeResult applyConfigurationChange(
-       AccessLogPublisherCfg config)
-   {
-     // Default result code.
-     ResultCode resultCode = ResultCode.SUCCESS;
-     boolean adminActionRequired = false;
-     ArrayList<Message> messages = new ArrayList<Message>();
+  public ConfigChangeResult applyConfigurationChange(
+      AccessLogPublisherCfg config)
+  {
+    // Default result code.
+    ResultCode resultCode = ResultCode.SUCCESS;
+    boolean adminActionRequired = false;
+    ArrayList<Message> messages = new ArrayList<Message>();
 
-     DN dn = config.dn();
+    DN dn = config.dn();
 
     AccessLogPublisher accessLogPublisher = null;
     for(AccessLogPublisher publisher : accessPublishers)
@@ -250,47 +251,47 @@
       }
     }
 
-     if(accessLogPublisher == null)
-     {
-       if(config.isEnabled())
-       {
-         // Needs to be added and enabled.
-         return applyConfigurationAdd(config);
-       }
-     }
-     else
-     {
-       if(config.isEnabled())
-       {
-         // The publisher is currently active, so we don't need to do anything.
-         // Changes to the class name cannot be
-         // applied dynamically, so if the class name did change then
-         // indicate that administrative action is required for that
-         // change to take effect.
-         String className = config.getJavaClass();
-         if(!className.equals(accessLogPublisher.getClass().getName()))
-         {
-           adminActionRequired = true;
-         }
-       }
-       else
-       {
-         // The publisher is being disabled so shut down and remove.
-         removeAccessLogPublisher(accessLogPublisher);
-       }
-     }
+    if(accessLogPublisher == null)
+    {
+      if(config.isEnabled())
+      {
+        // Needs to be added and enabled.
+        return applyConfigurationAdd(config);
+      }
+    }
+    else
+    {
+      if(config.isEnabled())
+      {
+        // The publisher is currently active, so we don't need to do anything.
+        // Changes to the class name cannot be
+        // applied dynamically, so if the class name did change then
+        // indicate that administrative action is required for that
+        // change to take effect.
+        String className = config.getJavaClass();
+        if(!className.equals(accessLogPublisher.getClass().getName()))
+        {
+          adminActionRequired = true;
+        }
+      }
+      else
+      {
+        // The publisher is being disabled so shut down and remove.
+        removeAccessLogPublisher(accessLogPublisher);
+      }
+    }
 
-     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-   }
+    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+  }
 
   /**
    * {@inheritDoc}
    */
-   public boolean isConfigurationDeleteAcceptable(
-          AccessLogPublisherCfg config,
-          List<Message> unacceptableReasons)
-   {
-     DN dn = config.dn();
+  public boolean isConfigurationDeleteAcceptable(
+      AccessLogPublisherCfg config,
+      List<Message> unacceptableReasons)
+  {
+    DN dn = config.dn();
 
     AccessLogPublisher accessLogPublisher = null;
     for(AccessLogPublisher publisher : accessPublishers)
@@ -302,14 +303,14 @@
       }
     }
 
-     return accessLogPublisher != null;
+    return accessLogPublisher != null;
 
-   }
+  }
 
   /**
    * {@inheritDoc}
    */
-   public ConfigChangeResult applyConfigurationDelete(
+  public ConfigChangeResult applyConfigurationDelete(
       AccessLogPublisherCfg config)
   {
     // Default result code.
@@ -338,92 +339,92 @@
     return new ConfigChangeResult(resultCode, adminActionRequired);
   }
 
-   private boolean isJavaClassAcceptable(AccessLogPublisherCfg config,
-                                         List<Message> unacceptableReasons)
-   {
-     String className = config.getJavaClass();
-     AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
-     ClassPropertyDefinition pd =
-         d.getJavaClassPropertyDefinition();
-     // Load the class and cast it to a DebugLogPublisher.
-     AccessLogPublisher publisher = null;
-     Class<? extends AccessLogPublisher> theClass;
-     try {
-       theClass = pd.loadClass(className, AccessLogPublisher.class);
-       publisher = theClass.newInstance();
-     } catch (Exception e) {
-       Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
-               className,
-               config.dn().toString(),
-               String.valueOf(e));
-       unacceptableReasons.add(message);
-       return false;
-     }
-     // Check that the implementation class implements the correct interface.
-     try {
-       // Determine the initialization method to use: it must take a
-       // single parameter which is the exact type of the configuration
-       // object.
-       Method method = theClass.getMethod("isConfigurationAcceptable",
-                                          AccessLogPublisherCfg.class,
-                                          List.class);
-       Boolean acceptable = (Boolean) method.invoke(publisher, config,
-                                                    unacceptableReasons);
+  private boolean isJavaClassAcceptable(AccessLogPublisherCfg config,
+                                        List<Message> unacceptableReasons)
+  {
+    String className = config.getJavaClass();
+    AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
+    ClassPropertyDefinition pd =
+        d.getJavaClassPropertyDefinition();
+    // Load the class and cast it to a DebugLogPublisher.
+    AccessLogPublisher publisher = null;
+    Class<? extends AccessLogPublisher> theClass;
+    try {
+      theClass = pd.loadClass(className, AccessLogPublisher.class);
+      publisher = theClass.newInstance();
+    } catch (Exception e) {
+      Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+          className,
+          config.dn().toString(),
+          String.valueOf(e));
+      unacceptableReasons.add(message);
+      return false;
+    }
+    // Check that the implementation class implements the correct interface.
+    try {
+      // Determine the initialization method to use: it must take a
+      // single parameter which is the exact type of the configuration
+      // object.
+      Method method = theClass.getMethod("isConfigurationAcceptable",
+          AccessLogPublisherCfg.class,
+          List.class);
+      Boolean acceptable = (Boolean) method.invoke(publisher, config,
+          unacceptableReasons);
 
-       if (! acceptable)
-       {
-         return false;
-       }
-     } catch (Exception e) {
-       Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
-               className,
-               config.dn().toString(),
-               String.valueOf(e));
-       unacceptableReasons.add(message);
-       return false;
-     }
-     // The class is valid as far as we can tell.
-     return true;
-   }
+      if (! acceptable)
+      {
+        return false;
+      }
+    } catch (Exception e) {
+      Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+          className,
+          config.dn().toString(),
+          String.valueOf(e));
+      unacceptableReasons.add(message);
+      return false;
+    }
+    // The class is valid as far as we can tell.
+    return true;
+  }
 
-   private AccessLogPublisher getAccessPublisher(AccessLogPublisherCfg config)
-       throws ConfigException {
-     String className = config.getJavaClass();
-     AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
-     ClassPropertyDefinition pd =
-         d.getJavaClassPropertyDefinition();
-     // Load the class and cast it to a AccessLogPublisher.
-     Class<? extends AccessLogPublisher> theClass;
-     AccessLogPublisher AccessLogPublisher;
-     try {
-       theClass = pd.loadClass(className, AccessLogPublisher.class);
-       AccessLogPublisher = theClass.newInstance();
+  private AccessLogPublisher getAccessPublisher(AccessLogPublisherCfg config)
+      throws ConfigException {
+    String className = config.getJavaClass();
+    AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
+    ClassPropertyDefinition pd =
+        d.getJavaClassPropertyDefinition();
+    // Load the class and cast it to a AccessLogPublisher.
+    Class<? extends AccessLogPublisher> theClass;
+    AccessLogPublisher AccessLogPublisher;
+    try {
+      theClass = pd.loadClass(className, AccessLogPublisher.class);
+      AccessLogPublisher = theClass.newInstance();
 
-       // Determine the initialization method to use: it must take a
-       // single parameter which is the exact type of the configuration
-       // object.
-       Method method = theClass.getMethod("initializeAccessLogPublisher", config
+      // Determine the initialization method to use: it must take a
+      // single parameter which is the exact type of the configuration
+      // object.
+      Method method = theClass.getMethod("initializeAccessLogPublisher", config
           .configurationClass());
-       method.invoke(AccessLogPublisher, config);
-     }
-     catch (InvocationTargetException ite)
-     {
-       // Rethrow the exceptions thrown be the invoked method.
-       Throwable e = ite.getTargetException();
-       Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
-           className, config.dn().toString(), stackTraceToSingleLineString(e));
-       throw new ConfigException(message, e);
-     }
-     catch (Exception e)
-     {
-       Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
-           className, config.dn().toString(), String.valueOf(e));
-       throw new ConfigException(message, e);
-     }
+      method.invoke(AccessLogPublisher, config);
+    }
+    catch (InvocationTargetException ite)
+    {
+      // Rethrow the exceptions thrown be the invoked method.
+      Throwable e = ite.getTargetException();
+      Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+          className, config.dn().toString(), stackTraceToSingleLineString(e));
+      throw new ConfigException(message, e);
+    }
+    catch (Exception e)
+    {
+      Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+          className, config.dn().toString(), String.valueOf(e));
+      throw new ConfigException(message, e);
+    }
 
-     // The access publisher has been successfully initialized.
-     return AccessLogPublisher;
-   }
+    // The access publisher has been successfully initialized.
+    return AccessLogPublisher;
+  }
 
 
 
@@ -569,7 +570,7 @@
 
 
   /**
- * Writes a message to the access logger with information about the compare
+   * Writes a message to the access logger with information about the compare
    * request associated with the provided compare operation.
    *
    * @param  compareOperation  The compare operation containing the information
diff --git a/opends/src/server/org/opends/server/types/AbstractOperation.java b/opends/src/server/org/opends/server/types/AbstractOperation.java
index 7866fca..2ba15a7 100644
--- a/opends/src/server/org/opends/server/types/AbstractOperation.java
+++ b/opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.types;
 import org.opends.messages.Message;
@@ -74,16 +74,6 @@
    */
   protected static boolean useNanoTime = false;
 
-  static
-  {
-    if(System.getProperty(PROPERTY_ETIME_NANO) != null &&
-         System.getProperty(PROPERTY_ETIME_NANO).
-            equalsIgnoreCase("true"))
-    {
-      useNanoTime = true;
-    }
-  }
-
 
   /**
    * The client connection with which this operation is associated.
@@ -104,6 +94,12 @@
   protected final long operationID;
 
 
+  /**
+   * Wether nanotime was used for this operation.
+   */
+  protected final boolean usingNanoTime;
+
+
 
   // Indicates whether this is an internal operation triggered within
   // the server itself rather than requested by an external client.
@@ -172,6 +168,7 @@
     this.clientConnection = clientConnection;
     this.operationID      = operationID;
     this.messageID        = messageID;
+    this.usingNanoTime    = useNanoTime;
 
     if (requestControls == null)
     {
@@ -1045,7 +1042,7 @@
    */
   public final void setProcessingStartTime()
   {
-    if(useNanoTime)
+    if(usingNanoTime)
     {
       processingStartTime = System.nanoTime();
     }
@@ -1078,7 +1075,7 @@
    */
   public final void setProcessingStopTime()
   {
-    if(useNanoTime)
+    if(usingNanoTime)
     {
       this.processingStopTime = System.nanoTime();
     }
@@ -1091,12 +1088,13 @@
 
 
   /**
-   * Retrieves the length of time in milliseconds that the server
-   * spent processing this operation.  This should not be called until
-   * after the server has sent the response to the client.
+   * Retrieves the length of time in milliseconds or nanoseconds that
+   * the server spent processing this operation.  This should not be
+   * called until after the server has sent the response to the
+   * client.
    *
-   * @return  The length of time in milliseconds that the server spent
-   *          processing this operation.
+   * @return  The length of time in milliseconds or nanoseconds that
+   *          the server spent processing this operation.
    */
   public final long getProcessingTime()
   {
@@ -1106,6 +1104,35 @@
 
 
   /**
+   * Set whether to use nanoTime for the processing time methods.
+   *
+   * @param useNanoTime <code>true</code> to use System.nanoTime
+   *                    or <code>false</code> to use
+   *                    System.currentTimeMillis
+   */
+  public static void setUseNanoTime(boolean useNanoTime)
+  {
+    AbstractOperation.useNanoTime = useNanoTime;
+  }
+
+
+
+  /**
+   * Get whether this operation used System.nanoTime or
+   * System.currentTimeMillis for the processing time methods.
+   *
+   * @return  <code>true</code> if System.nanoTime is used or
+   *          <code>false</code> if System.currentTimeMillis
+   *          was used.
+   */
+  public final boolean getUseNanoTime()
+  {
+    return usingNanoTime;
+  }
+
+
+
+  /**
    * Performs the work of actually processing this operation.  This
    * should include all processing for the operation, including
    * invoking pre-parse and post-response plugins, logging messages
diff --git a/opends/src/server/org/opends/server/util/ServerConstants.java b/opends/src/server/org/opends/server/util/ServerConstants.java
index eb68b8f..6c047fb 100644
--- a/opends/src/server/org/opends/server/util/ServerConstants.java
+++ b/opends/src/server/org/opends/server/util/ServerConstants.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.util;
 
@@ -2770,14 +2770,6 @@
        "org.opends.server.UseLastKnownGoodConfiguration";
 
 
-  /**
-   * The name of the system property that can be used to configure the
-   * server to report etimes in nanoseconds instead of milliseconds.
-   */
-  public static final String PROPERTY_ETIME_NANO =
-      "org.opends.server.etime.nano";
-
-
 
   /**
    * The column at which to wrap long lines of output in the command-line tools.
diff --git a/opends/src/server/org/opends/server/util/TimeThread.java b/opends/src/server/org/opends/server/util/TimeThread.java
index 27a311d..63e9c12 100644
--- a/opends/src/server/org/opends/server/util/TimeThread.java
+++ b/opends/src/server/org/opends/server/util/TimeThread.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.util;
 
@@ -93,6 +93,9 @@
   // The current time in milliseconds since the epoch.
   private static volatile long time;
 
+  // The current time in nanoseconds.
+  private static volatile long nanoTime;
+
   // The date formatter that will be used to obtain the generalized time.
   private static SimpleDateFormat generalizedTimeFormatter;
 
@@ -139,6 +142,7 @@
     calendar        = new GregorianCalendar();
     date            = calendar.getTime();
     time            = date.getTime();
+    nanoTime        = System.nanoTime();
     generalizedTime = generalizedTimeFormatter.format(date);
     localTimestamp  = localTimestampFormatter.format(date);
     gmtTimestamp    = gmtTimestampFormatter.format(date);
@@ -163,6 +167,7 @@
         calendar        = new GregorianCalendar();
         date            = calendar.getTime();
         time            = date.getTime();
+        nanoTime        = System.nanoTime();
         generalizedTime = generalizedTimeFormatter.format(date);
         localTimestamp  = localTimestampFormatter.format(date);
         gmtTimestamp    = gmtTimestampFormatter.format(date);
@@ -223,6 +228,18 @@
     return time;
   }
 
+  /**
+   * Retrieves the time in nanoseconds from the most precise available system
+   * timer. The value retured represents nanoseconds since some fixed but
+   * arbitrary time.
+   *
+   * @return The time in nanoseconds from some fixed but arbitrary time.
+   */
+  public static long getNanoTime()
+  {
+    return nanoTime;
+  }
+
 
 
   /**

--
Gitblit v1.10.0