This is an automated email from the ASF dual-hosted git repository.

sammichen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 6839345233 HDDS-8745. Let ConfigType.TIME apply to Duration (#4932)
6839345233 is described below

commit 68393452332a2d881c34eb2c21feee4b1a8e58e9
Author: Doroszlai, Attila <[email protected]>
AuthorDate: Fri Oct 27 05:41:31 2023 +0200

    HDDS-8745. Let ConfigType.TIME apply to Duration (#4932)
---
 .../java/org/apache/hadoop/hdds/fs/DUFactory.java  |  6 +-
 .../hdds/fs/DedicatedDiskSpaceUsageFactory.java    |  8 +--
 .../hadoop/hdds/ratis/conf/RatisClientConfig.java  | 39 +++++------
 .../java/org/apache/hadoop/hdds/scm/ScmConfig.java |  6 +-
 .../hadoop/hdds/conf/SimpleConfiguration.java      | 17 +++++
 .../hadoop/hdds/conf/TestOzoneConfiguration.java   |  9 +++
 .../org/apache/hadoop/hdds/conf/ConfigType.java    | 79 +++++++++++++++++++++-
 .../hdds/conf/ConfigurationReflectionUtil.java     | 52 ++------------
 .../hadoop/hdds/conf/ConfigurationTarget.java      |  5 ++
 .../apache/hadoop/hdds/conf/TimeDurationUtil.java  | 61 +++++++++++++++--
 .../hadoop/hdds/conf/ConfigurationExample.java     | 10 +++
 .../common/statemachine/DatanodeConfiguration.java | 39 +++++------
 .../statemachine/TestDatanodeConfiguration.java    |  8 +--
 .../container/replication/ReplicationManager.java  | 18 ++---
 .../hadoop/ozone/recon/tasks/ReconTaskConfig.java  | 25 ++++---
 15 files changed, 249 insertions(+), 133 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DUFactory.java 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DUFactory.java
index 19eea03cd4..3d31749803 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DUFactory.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DUFactory.java
@@ -69,14 +69,14 @@ public class DUFactory implements SpaceUsageCheckFactory {
         description = "Disk space usage information will be refreshed with the"
             + "specified period following the completion of the last check."
     )
-    private long refreshPeriod;
+    private Duration refreshPeriod;
 
     public void setRefreshPeriod(Duration duration) {
-      refreshPeriod = duration.toMillis();
+      refreshPeriod = duration;
     }
 
     public Duration getRefreshPeriod() {
-      return Duration.ofMillis(refreshPeriod);
+      return refreshPeriod;
     }
   }
 }
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DedicatedDiskSpaceUsageFactory.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DedicatedDiskSpaceUsageFactory.java
index 2292a7359d..0aae5bb0d8 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DedicatedDiskSpaceUsageFactory.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/DedicatedDiskSpaceUsageFactory.java
@@ -69,14 +69,10 @@ public class DedicatedDiskSpaceUsageFactory implements 
SpaceUsageCheckFactory {
         description = "Disk space usage information will be refreshed with the"
             + "specified period following the completion of the last check."
     )
-    private long refreshPeriod;
-
-    public void setRefreshPeriod(long millis) {
-      refreshPeriod = millis;
-    }
+    private Duration refreshPeriod;
 
     public Duration getRefreshPeriod() {
-      return Duration.ofMillis(refreshPeriod);
+      return refreshPeriod;
     }
 
     static String configKeyForRefreshPeriod() {
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/conf/RatisClientConfig.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/conf/RatisClientConfig.java
index 7db60598e1..c21e25d0b6 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/conf/RatisClientConfig.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/conf/RatisClientConfig.java
@@ -69,14 +69,14 @@ public class RatisClientConfig {
         "The timeout duration for ratis client request (except "
             + "for watch request). It should be set greater than leader "
             + "election timeout in Ratis.")
-    private long rpcRequestTimeout = Duration.ofSeconds(60).toMillis();
+    private Duration rpcRequestTimeout = Duration.ofSeconds(60);
 
     public Duration getRpcRequestTimeout() {
-      return Duration.ofMillis(rpcRequestTimeout);
+      return rpcRequestTimeout;
     }
 
     public void setRpcRequestTimeout(Duration duration) {
-      this.rpcRequestTimeout = duration.toMillis();
+      rpcRequestTimeout = duration;
     }
 
     @Config(key = "rpc.watch.request.timeout",
@@ -87,14 +87,14 @@ public class RatisClientConfig {
         "The timeout duration for ratis client watch request. "
             + "Timeout for the watch API in Ratis client to acknowledge a "
             + "particular request getting replayed to all servers.")
-    private long rpcWatchRequestTimeout = Duration.ofSeconds(180).toMillis();
+    private Duration rpcWatchRequestTimeout = Duration.ofSeconds(180);
 
     public Duration getRpcWatchRequestTimeout() {
-      return Duration.ofMillis(rpcWatchRequestTimeout);
+      return rpcWatchRequestTimeout;
     }
 
     public void setRpcWatchRequestTimeout(Duration duration) {
-      this.rpcWatchRequestTimeout = duration.toMillis();
+      rpcWatchRequestTimeout = duration;
     }
   }
 
@@ -103,15 +103,14 @@ public class RatisClientConfig {
       type = ConfigType.TIME,
       tags = { OZONE, CLIENT, PERFORMANCE },
       description = "Timeout for ratis client write request.")
-  private long writeRequestTimeoutInMs =
-      Duration.ofMinutes(5).toMillis();
+  private Duration writeRequestTimeout = Duration.ofMinutes(5);
 
   public Duration getWriteRequestTimeout() {
-    return Duration.ofMillis(writeRequestTimeoutInMs);
+    return writeRequestTimeout;
   }
 
   public void setWriteRequestTimeout(Duration duration) {
-    writeRequestTimeoutInMs = duration.toMillis();
+    writeRequestTimeout = duration;
   }
 
   @Config(key = "client.request.watch.timeout",
@@ -119,14 +118,14 @@ public class RatisClientConfig {
       type = ConfigType.TIME,
       tags = { OZONE, CLIENT, PERFORMANCE },
       description = "Timeout for ratis client watch request.")
-  private long watchRequestTimeoutInMs = Duration.ofMinutes(3).toMillis();
+  private Duration watchRequestTimeout = Duration.ofMinutes(3);
 
   public Duration getWatchRequestTimeout() {
-    return Duration.ofMillis(watchRequestTimeoutInMs);
+    return watchRequestTimeout;
   }
 
   public void setWatchRequestTimeout(Duration duration) {
-    watchRequestTimeoutInMs = duration.toMillis();
+    watchRequestTimeout = duration;
   }
 
   @Config(key = "client.multilinear.random.retry.policy",
@@ -156,15 +155,14 @@ public class RatisClientConfig {
           + " With the default base sleep of 4s, the sleep duration for ith"
           + " retry is min(4 * pow(2, i), max_sleep) * r, where r is "
           + "random number in the range [0.5, 1.5).")
-  private long exponentialPolicyBaseSleepInMs =
-      Duration.ofSeconds(4).toMillis();
+  private Duration exponentialPolicyBaseSleep = Duration.ofSeconds(4);
 
   public Duration getExponentialPolicyBaseSleep() {
-    return Duration.ofMillis(exponentialPolicyBaseSleepInMs);
+    return exponentialPolicyBaseSleep;
   }
 
   public void setExponentialPolicyBaseSleep(Duration duration) {
-    exponentialPolicyBaseSleepInMs = duration.toMillis();
+    exponentialPolicyBaseSleep = duration;
   }
 
   @Config(key = "client.exponential.backoff.max.sleep",
@@ -175,15 +173,14 @@ public class RatisClientConfig {
           + "policy is limited by the configured max sleep. Refer "
           + "dfs.ratis.client.exponential.backoff.base.sleep for further "
           + "details.")
-  private long exponentialPolicyMaxSleepInMs =
-      Duration.ofSeconds(40).toMillis();
+  private Duration exponentialPolicyMaxSleep = Duration.ofSeconds(40);
 
   public Duration getExponentialPolicyMaxSleep() {
-    return Duration.ofMillis(exponentialPolicyMaxSleepInMs);
+    return exponentialPolicyMaxSleep;
   }
 
   public void setExponentialPolicyMaxSleep(Duration duration) {
-    exponentialPolicyMaxSleepInMs = duration.toMillis();
+    exponentialPolicyMaxSleep = duration;
   }
 
   @Config(key = "client.retrylimited.retry.interval",
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfig.java 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfig.java
index 521ffef919..46816a63d3 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfig.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfig.java
@@ -117,7 +117,7 @@ public class ScmConfig extends ReconfigurableConfig {
               + "queued for deletion. Unit could be defined with "
               + "postfix (ns,ms,s,m,h,d). "
   )
-  private long blockDeletionInterval = Duration.ofSeconds(60).toMillis();
+  private Duration blockDeletionInterval = Duration.ofSeconds(60);
 
   @Config(key = "init.default.layout.version",
       defaultValue = "-1",
@@ -131,11 +131,11 @@ public class ScmConfig extends ReconfigurableConfig {
   private int defaultLayoutVersionOnInit = -1;
 
   public Duration getBlockDeletionInterval() {
-    return Duration.ofMillis(blockDeletionInterval);
+    return blockDeletionInterval;
   }
 
   public void setBlockDeletionInterval(Duration duration) {
-    this.blockDeletionInterval = duration.toMillis();
+    blockDeletionInterval = duration;
   }
 
   public void setKerberosPrincipal(String kerberosPrincipal) {
diff --git 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/SimpleConfiguration.java
 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/SimpleConfiguration.java
index a48bbcdb3b..67a8a2a740 100644
--- 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/SimpleConfiguration.java
+++ 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/SimpleConfiguration.java
@@ -17,6 +17,7 @@
  */
 package org.apache.hadoop.hdds.conf;
 
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -59,6 +60,14 @@ public class SimpleConfiguration extends 
SimpleConfigurationParent {
       tags = ConfigTag.MANAGEMENT)
   private long waitTime;
 
+  @Config(key = "duration",
+      type = ConfigType.TIME,
+      timeUnit = TimeUnit.MINUTES,
+      defaultValue = "1h",
+      description = "N/A",
+      tags = ConfigTag.MANAGEMENT)
+  private Duration duration;
+
   @Config(key = "class",
       type = ConfigType.CLASS,
       defaultValue = "java.lang.Object",
@@ -139,4 +148,12 @@ public class SimpleConfiguration extends 
SimpleConfigurationParent {
   public void setThreshold(double threshold) {
     this.threshold = threshold;
   }
+
+  public Duration getDuration() {
+    return duration;
+  }
+
+  public void setDuration(Duration duration) {
+    this.duration = duration;
+  }
 }
diff --git 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/TestOzoneConfiguration.java
 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/TestOzoneConfiguration.java
index 3f580a1a1b..97b62a138f 100644
--- 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/TestOzoneConfiguration.java
+++ 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/conf/TestOzoneConfiguration.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.hadoop.conf.Configuration;
@@ -113,6 +114,8 @@ public class TestOzoneConfiguration {
     ozoneConfig.setBoolean("test.scm.client.enabled", true);
     ozoneConfig.setInt("test.scm.client.port", 5555);
     ozoneConfig.setTimeDuration("test.scm.client.wait", 10, TimeUnit.MINUTES);
+    ozoneConfig.setTimeDuration("test.scm.client.duration",
+        3, TimeUnit.SECONDS);
     ozoneConfig.set("test.scm.client.class", Integer.class.getName());
     ozoneConfig.setDouble("test.scm.client.threshold", 10.5);
 
@@ -126,6 +129,7 @@ public class TestOzoneConfiguration {
     Assertions.assertEquals(600, configuration.getWaitTime());
     Assertions.assertSame(Integer.class, configuration.getMyClass());
     Assertions.assertEquals(10.5, configuration.getThreshold());
+    Assertions.assertEquals(Duration.ofSeconds(3), 
configuration.getDuration());
   }
 
   @Test
@@ -139,6 +143,7 @@ public class TestOzoneConfiguration {
     Assertions.assertEquals(9878, configuration.getPort());
     Assertions.assertSame(Object.class, configuration.getMyClass());
     Assertions.assertEquals(10, configuration.getThreshold());
+    Assertions.assertEquals(Duration.ofHours(1), configuration.getDuration());
   }
 
   @Test
@@ -152,6 +157,7 @@ public class TestOzoneConfiguration {
     object.setWaitTime(600);
     object.setMyClass(this.getClass());
     object.setThreshold(10.5);
+    object.setDuration(Duration.ofMillis(100));
 
     OzoneConfiguration subject = new OzoneConfiguration();
 
@@ -173,6 +179,9 @@ public class TestOzoneConfiguration {
         subject.getClass("test.scm.client.class", null));
     Assertions.assertEquals(object.getThreshold(),
         subject.getDouble("test.scm.client.threshold", 20.5));
+    Assertions.assertEquals(object.getDuration().toMillis(),
+        subject.getTimeDuration("test.scm.client.duration", 0,
+            TimeUnit.MILLISECONDS));
   }
 
   @Test
diff --git 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigType.java 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigType.java
index 96c6f0ed84..4ed59669a9 100644
--- 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigType.java
+++ 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigType.java
@@ -17,6 +17,10 @@
  */
 package org.apache.hadoop.hdds.conf;
 
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.hadoop.hdds.conf.TimeDurationUtil.getDuration;
 import static 
org.apache.hadoop.hdds.conf.TimeDurationUtil.getTimeDurationHelper;
 
 /**
@@ -32,6 +36,11 @@ public enum ConfigType {
       throw new UnsupportedOperationException();
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      throw new UnsupportedOperationException();
+    }
   },
   STRING {
     @Override
@@ -39,6 +48,11 @@ public enum ConfigType {
       return value;
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      target.set(key, String.valueOf(value));
+    }
   },
   BOOLEAN {
     @Override
@@ -46,6 +60,11 @@ public enum ConfigType {
       return Boolean.parseBoolean(value);
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      target.setBoolean(key, (boolean) value);
+    }
   },
   INT {
     @Override
@@ -53,6 +72,11 @@ public enum ConfigType {
       return Integer.parseInt(value);
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      target.setInt(key, (int) value);
+    }
   },
   LONG {
     @Override
@@ -60,13 +84,36 @@ public enum ConfigType {
       return Long.parseLong(value);
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      target.setLong(key, (long) value);
+    }
   },
   TIME {
     @Override
-    Long parse(String value, Config config, Class<?> type, String key) {
+    Object parse(String value, Config config, Class<?> type, String key) {
+      if (type == Duration.class) {
+        return getDuration(key, value, config.timeUnit());
+      }
       return getTimeDurationHelper(key, value, config.timeUnit());
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      if (value instanceof Duration) {
+        final Duration duration = (Duration) value;
+        if (duration.getNano() % 1_000_000 > 0) {
+          target.setTimeDuration(key, duration.toNanos(), 
TimeUnit.NANOSECONDS);
+        } else {
+          final long millis = duration.toMillis();
+          target.setTimeDuration(key, millis, TimeUnit.MILLISECONDS);
+        }
+      } else {
+        target.setTimeDuration(key, (long) value, config.timeUnit());
+      }
+    }
   },
   SIZE {
     @Override
@@ -79,6 +126,18 @@ public enum ConfigType {
       return val;
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      if (value instanceof Long) {
+        target.setStorageSize(key, (long) value, StorageUnit.BYTES);
+      } else if (value instanceof Integer) {
+        target.setStorageSize(key, (int) value, StorageUnit.BYTES);
+      } else {
+        throw new ConfigurationException("Unsupported type " + value.getClass()
+            + " for " + key);
+      }
+    }
   },
   CLASS {
     @Override
@@ -87,6 +146,16 @@ public enum ConfigType {
       return Class.forName(value);
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      if (value instanceof Class<?>) {
+        target.set(key, ((Class<?>) value).getName());
+      } else {
+        throw new ConfigurationException("Unsupported type " + value.getClass()
+            + " for " + key);
+      }
+    }
   },
   DOUBLE {
     @Override
@@ -94,8 +163,16 @@ public enum ConfigType {
       return Double.parseDouble(value);
     }
 
+    @Override
+    void set(ConfigurationTarget target, String key, Object value,
+        Config config) {
+      target.setDouble(key, (double) value);
+    }
   };
 
   abstract Object parse(String value, Config config, Class<?> type, String key)
       throws Exception;
+
+  abstract void set(ConfigurationTarget target, String key, Object value,
+      Config config);
 }
diff --git 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationReflectionUtil.java
 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationReflectionUtil.java
index d5c9587a2b..d1ccc58be1 100644
--- 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationReflectionUtil.java
+++ 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationReflectionUtil.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.time.Duration;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -202,6 +203,8 @@ public final class ConfigurationReflectionUtil {
     } else if (parameterType == Boolean.class
         || parameterType == boolean.class) {
       type = ConfigType.BOOLEAN;
+    } else if (parameterType == Duration.class) {
+      type = ConfigType.TIME;
     } else if (parameterType == Class.class) {
       type = ConfigType.CLASS;
     } else {
@@ -270,56 +273,15 @@ public final class ConfigurationReflectionUtil {
 
         //Note: default value is handled by ozone-default.xml. Here we can
         //use any default.
-        boolean accessChanged = false;
         try {
-          if (!field.isAccessible()) {
-            field.setAccessible(true);
-            accessChanged = true;
-          }
-          switch (type) {
-          case STRING:
-            Object value = field.get(configObject);
-            if (value != null) {
-              config.set(key, String.valueOf(value));
-            }
-            break;
-          case INT:
-            config.setInt(key, field.getInt(configObject));
-            break;
-          case BOOLEAN:
-            config.setBoolean(key, field.getBoolean(configObject));
-            break;
-          case LONG:
-            config.setLong(key, field.getLong(configObject));
-            break;
-          case DOUBLE:
-            config.setDouble(key, field.getDouble(configObject));
-            break;
-          case TIME:
-            config.setTimeDuration(key, field.getLong(configObject),
-                configAnnotation.timeUnit());
-            break;
-          case SIZE:
-            config.setStorageSize(key, field.getLong(configObject),
-                StorageUnit.BYTES);
-            break;
-          case CLASS:
-            Object valueClass = field.get(configObject);
-            if (valueClass instanceof Class<?>) {
-              config.set(key, ((Class<?>) valueClass).getName());
-            }
-            break;
-          default:
-            throw new ConfigurationException(
-                "Unsupported ConfigType " + type + " on " + fieldLocation);
+          Object value = forcedFieldGet(field, configObject);
+          if (value == null) {
+            continue;
           }
+          type.set(config, key, value, configAnnotation);
         } catch (IllegalAccessException e) {
           throw new ConfigurationException(
               "Can't inject configuration to " + fieldLocation, e);
-        } finally {
-          if (accessChanged) {
-            field.setAccessible(false);
-          }
         }
       }
     }
diff --git 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationTarget.java
 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationTarget.java
index d4bfb360b9..7ac5d885e3 100644
--- 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationTarget.java
+++ 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/ConfigurationTarget.java
@@ -17,6 +17,7 @@
  */
 package org.apache.hadoop.hdds.conf;
 
+import java.time.temporal.TemporalUnit;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.hadoop.hdds.conf.TimeDurationUtil.ParsedTimeDuration;
@@ -52,6 +53,10 @@ public interface ConfigurationTarget {
     set(name, value + ParsedTimeDuration.unitFor(unit).suffix());
   }
 
+  default void setTimeDuration(String name, long value, TemporalUnit unit) {
+    set(name, value + ParsedTimeDuration.unitFor(unit).suffix());
+  }
+
   default void setStorageSize(String name, long value, StorageUnit unit) {
     set(name, value + unit.getShortName());
   }
diff --git 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/TimeDurationUtil.java
 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/TimeDurationUtil.java
index fa2b7328b7..c8775fbf94 100644
--- 
a/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/TimeDurationUtil.java
+++ 
b/hadoop-hdds/config/src/main/java/org/apache/hadoop/hdds/conf/TimeDurationUtil.java
@@ -17,6 +17,9 @@
  */
 package org.apache.hadoop.hdds.conf;
 
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalUnit;
 import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
@@ -44,6 +47,11 @@ public final class TimeDurationUtil {
    */
   public static long getTimeDurationHelper(String name, String vStr,
       TimeUnit unit) {
+    final long millis = getDuration(name, vStr, unit).toMillis();
+    return unit.convert(millis, TimeUnit.MILLISECONDS);
+  }
+
+  public static Duration getDuration(String name, String vStr, TimeUnit unit) {
     vStr = vStr.trim();
     vStr = vStr.toLowerCase();
     ParsedTimeDuration vUnit = ParsedTimeDuration.unitFor(vStr);
@@ -58,12 +66,7 @@ public final class TimeDurationUtil {
     }
 
     long raw = Long.parseLong(vStr);
-    long converted = unit.convert(raw, vUnit.unit());
-    if (vUnit.unit().convert(converted, unit) < raw) {
-      LOG.warn("Possible loss of precision converting " + vStr
-          + vUnit.suffix() + " to " + unit + " for " + name);
-    }
-    return converted;
+    return Duration.of(raw, vUnit.temporalUnit());
   }
 
   enum ParsedTimeDuration {
@@ -77,6 +80,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "ns";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.NANOS;
+      }
     },
     US {
       @Override
@@ -88,6 +96,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "us";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.MICROS;
+      }
     },
     MS {
       @Override
@@ -99,6 +112,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "ms";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.MILLIS;
+      }
     },
     S {
       @Override
@@ -110,6 +128,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "s";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.SECONDS;
+      }
     },
     M {
       @Override
@@ -121,6 +144,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "m";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.MINUTES;
+      }
     },
     H {
       @Override
@@ -132,6 +160,11 @@ public final class TimeDurationUtil {
       String suffix() {
         return "h";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.HOURS;
+      }
     },
     D {
       @Override
@@ -143,12 +176,19 @@ public final class TimeDurationUtil {
       String suffix() {
         return "d";
       }
+
+      @Override
+      TemporalUnit temporalUnit() {
+        return ChronoUnit.DAYS;
+      }
     };
 
     abstract TimeUnit unit();
 
     abstract String suffix();
 
+    abstract TemporalUnit temporalUnit();
+
     static ParsedTimeDuration unitFor(String s) {
       for (ParsedTimeDuration ptd : values()) {
         // iteration order is in decl order, so SECONDS matched last
@@ -167,5 +207,14 @@ public final class TimeDurationUtil {
       }
       return null;
     }
+
+    static ParsedTimeDuration unitFor(TemporalUnit unit) {
+      for (ParsedTimeDuration ptd : values()) {
+        if (ptd.temporalUnit() == unit) {
+          return ptd;
+        }
+      }
+      return null;
+    }
   }
 }
diff --git 
a/hadoop-hdds/config/src/test/java/org/apache/hadoop/hdds/conf/ConfigurationExample.java
 
b/hadoop-hdds/config/src/test/java/org/apache/hadoop/hdds/conf/ConfigurationExample.java
index 1a2e76b59f..ff47921a4b 100644
--- 
a/hadoop-hdds/config/src/test/java/org/apache/hadoop/hdds/conf/ConfigurationExample.java
+++ 
b/hadoop-hdds/config/src/test/java/org/apache/hadoop/hdds/conf/ConfigurationExample.java
@@ -17,6 +17,7 @@
  */
 package org.apache.hadoop.hdds.conf;
 
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -47,6 +48,11 @@ public class ConfigurationExample extends 
ConfigurationExampleParent {
       + "test TIME config type)", tags = ConfigTag.MANAGEMENT)
   private long waitTime = 1;
 
+  @Config(key = "time.duration", type = ConfigType.TIME, timeUnit =
+      TimeUnit.MINUTES, defaultValue = "1h", description = "N/A",
+      tags = ConfigTag.MANAGEMENT)
+  private Duration duration = Duration.ofSeconds(5);
+
   @Config(key = "size.small", type = ConfigType.SIZE, defaultValue = "42MB",
       tags = {},
       description = "Testing SIZE with int field")
@@ -110,6 +116,10 @@ public class ConfigurationExample extends 
ConfigurationExampleParent {
     return waitTime;
   }
 
+  public Duration getDuration() {
+    return duration;
+  }
+
   public double getThreshold() {
     return threshold;
   }
diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
index 715faafa51..be1723a3de 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
@@ -89,11 +89,9 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
 
   static final boolean WAIT_ON_ALL_FOLLOWERS_DEFAULT = false;
 
-  static final long DISK_CHECK_MIN_GAP_DEFAULT =
-      Duration.ofMinutes(10).toMillis();
+  static final Duration DISK_CHECK_MIN_GAP_DEFAULT = Duration.ofMinutes(10);
 
-  static final long DISK_CHECK_TIMEOUT_DEFAULT =
-      Duration.ofMinutes(10).toMillis();
+  static final Duration DISK_CHECK_TIMEOUT_DEFAULT = Duration.ofMinutes(10);
 
   static final boolean CONTAINER_SCHEMA_V3_ENABLED_DEFAULT = true;
   static final long ROCKSDB_LOG_MAX_FILE_SIZE_BYTES_DEFAULT = 32 * 1024 * 1024;
@@ -210,7 +208,7 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
                           + "deletion. Unit could be defined with "
                           + "postfix (ns,ms,s,m,h,d). "
   )
-  private long blockDeletionInterval = Duration.ofSeconds(60).toMillis();
+  private Duration blockDeletionInterval = Duration.ofSeconds(60);
 
   @Config(key = "recovering.container.scrubbing.service.interval",
       defaultValue = "1m",
@@ -222,8 +220,7 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
               "on Datanode periodically and deletes stale recovering " +
               "container Unit could be defined with postfix (ns,ms,s,m,h,d)."
   )
-  private long recoveringContainerScrubInterval =
-      Duration.ofMinutes(10).toMillis();
+  private Duration recoveringContainerScrubInterval = Duration.ofMinutes(10);
 
   /**
    * The maximum time to wait for acquiring the container lock when processing
@@ -243,21 +240,19 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
       Duration.ofMillis(100).toMillis();
 
   public Duration getBlockDeletionInterval() {
-    return Duration.ofMillis(blockDeletionInterval);
+    return blockDeletionInterval;
   }
 
-  public void setRecoveringContainerScrubInterval(
-          Duration recoveringContainerScrubInterval) {
-    this.recoveringContainerScrubInterval =
-            recoveringContainerScrubInterval.toMillis();
+  public void setRecoveringContainerScrubInterval(Duration duration) {
+    recoveringContainerScrubInterval = duration;
   }
 
   public Duration getRecoveringContainerScrubInterval() {
-    return Duration.ofMillis(recoveringContainerScrubInterval);
+    return recoveringContainerScrubInterval;
   }
 
   public void setBlockDeletionInterval(Duration duration) {
-    this.blockDeletionInterval = duration.toMillis();
+    blockDeletionInterval = duration;
   }
 
   @Config(key = "block.deleting.limit.per.interval",
@@ -388,7 +383,7 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
           + " Datanode volume. Unit could be defined with"
           + " postfix (ns,ms,s,m,h,d)."
   )
-  private long diskCheckMinGap = DISK_CHECK_MIN_GAP_DEFAULT;
+  private Duration diskCheckMinGap = DISK_CHECK_MIN_GAP_DEFAULT;
 
   @Config(key = "disk.check.timeout",
       defaultValue = "10m",
@@ -399,7 +394,7 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
           + " then the disk is declared as failed. Unit could be defined with"
           + " postfix (ns,ms,s,m,h,d)."
   )
-  private long diskCheckTimeout = DISK_CHECK_TIMEOUT_DEFAULT;
+  private Duration diskCheckTimeout = DISK_CHECK_TIMEOUT_DEFAULT;
 
   @Config(key = "chunk.data.validation.check",
       defaultValue = "false",
@@ -625,14 +620,14 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
       }
     }
 
-    if (diskCheckMinGap < 0) {
+    if (diskCheckMinGap.isNegative()) {
       LOG.warn(DISK_CHECK_MIN_GAP_KEY +
               " must be greater than zero and was set to {}. Defaulting to {}",
           diskCheckMinGap, DISK_CHECK_MIN_GAP_DEFAULT);
       diskCheckMinGap = DISK_CHECK_MIN_GAP_DEFAULT;
     }
 
-    if (diskCheckTimeout < 0) {
+    if (diskCheckTimeout.isNegative()) {
       LOG.warn(DISK_CHECK_TIMEOUT_KEY +
               " must be greater than zero and was set to {}. Defaulting to {}",
           diskCheckTimeout, DISK_CHECK_TIMEOUT_DEFAULT);
@@ -741,19 +736,19 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
   }
 
   public Duration getDiskCheckMinGap() {
-    return Duration.ofMillis(diskCheckMinGap);
+    return diskCheckMinGap;
   }
 
   public void setDiskCheckMinGap(Duration duration) {
-    this.diskCheckMinGap = duration.toMillis();
+    diskCheckMinGap = duration;
   }
 
   public Duration getDiskCheckTimeout() {
-    return Duration.ofMillis(diskCheckTimeout);
+    return diskCheckTimeout;
   }
 
   public void setDiskCheckTimeout(Duration duration) {
-    this.diskCheckTimeout = duration.toMillis();
+    diskCheckTimeout = duration;
   }
 
   public int getBlockDeleteThreads() {
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
index 28e5fdd764..359023e8b8 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
@@ -131,9 +131,9 @@ public class TestDatanodeConfiguration {
     assertEquals(FAILED_VOLUMES_TOLERATED_DEFAULT,
         subject.getFailedDbVolumesTolerated());
     assertEquals(DISK_CHECK_MIN_GAP_DEFAULT,
-        subject.getDiskCheckMinGap().toMillis());
+        subject.getDiskCheckMinGap());
     assertEquals(DISK_CHECK_TIMEOUT_DEFAULT,
-        subject.getDiskCheckTimeout().toMillis());
+        subject.getDiskCheckTimeout());
   }
 
   @Test
@@ -156,9 +156,9 @@ public class TestDatanodeConfiguration {
     assertEquals(FAILED_VOLUMES_TOLERATED_DEFAULT,
         subject.getFailedDbVolumesTolerated());
     assertEquals(DISK_CHECK_MIN_GAP_DEFAULT,
-        subject.getDiskCheckMinGap().toMillis());
+        subject.getDiskCheckMinGap());
     assertEquals(DISK_CHECK_TIMEOUT_DEFAULT,
-        subject.getDiskCheckTimeout().toMillis());
+        subject.getDiskCheckTimeout());
   }
 
   @Test
diff --git 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java
 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java
index 734de07df3..ff804e40f3 100644
--- 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java
+++ 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java
@@ -1076,7 +1076,7 @@ public class ReplicationManager implements SCMService {
             "cluster. This property is used to configure the interval in " +
             "which that thread runs."
     )
-    private long interval = Duration.ofSeconds(300).toMillis();
+    private Duration interval = Duration.ofSeconds(300);
 
     /**
      * The frequency in which the Under Replicated queue is processed.
@@ -1089,7 +1089,7 @@ public class ReplicationManager implements SCMService {
         description = "How frequently to check if there are work to process " +
             " on the under replicated queue"
     )
-    private long underReplicatedInterval = Duration.ofSeconds(30).toMillis();
+    private Duration underReplicatedInterval = Duration.ofSeconds(30);
 
     /**
      * The frequency in which the Over Replicated queue is processed.
@@ -1102,7 +1102,7 @@ public class ReplicationManager implements SCMService {
         description = "How frequently to check if there are work to process " +
             " on the over replicated queue"
     )
-    private long overReplicatedInterval = Duration.ofSeconds(30).toMillis();
+    private Duration overReplicatedInterval = Duration.ofSeconds(30);
 
     /**
      * Timeout for container replication & deletion command issued by
@@ -1118,7 +1118,7 @@ public class ReplicationManager implements SCMService {
             + "retried.")
     private long eventTimeout = Duration.ofMinutes(10).toMillis();
     public void setInterval(Duration interval) {
-      this.interval = interval.toMillis();
+      this.interval = interval;
     }
 
     public void setEventTimeout(Duration timeout) {
@@ -1294,23 +1294,23 @@ public class ReplicationManager implements SCMService {
     }
 
     public Duration getInterval() {
-      return Duration.ofMillis(interval);
+      return interval;
     }
 
     public Duration getUnderReplicatedInterval() {
-      return Duration.ofMillis(underReplicatedInterval);
+      return underReplicatedInterval;
     }
 
     public void setUnderReplicatedInterval(Duration duration) {
-      this.underReplicatedInterval = duration.toMillis();
+      this.underReplicatedInterval = duration;
     }
 
     public void setOverReplicatedInterval(Duration duration) {
-      this.overReplicatedInterval = duration.toMillis();
+      this.overReplicatedInterval = duration;
     }
 
     public Duration getOverReplicatedInterval() {
-      return Duration.ofMillis(overReplicatedInterval);
+      return overReplicatedInterval;
     }
 
     public long getEventTimeout() {
diff --git 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/ReconTaskConfig.java
 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/ReconTaskConfig.java
index 8b4fd8ad85..3c0a771356 100644
--- 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/ReconTaskConfig.java
+++ 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/ReconTaskConfig.java
@@ -38,14 +38,14 @@ public class ReconTaskConfig {
       description = "The time interval of periodic sync of pipeline state " +
           "from SCM to Recon."
   )
-  private long pipelineSyncTaskInterval = Duration.ofMinutes(5).toMillis();
+  private Duration pipelineSyncTaskInterval = Duration.ofMinutes(5);
 
   public Duration getPipelineSyncTaskInterval() {
-    return Duration.ofMillis(pipelineSyncTaskInterval);
+    return pipelineSyncTaskInterval;
   }
 
   public void setPipelineSyncTaskInterval(Duration interval) {
-    this.pipelineSyncTaskInterval = interval.toMillis();
+    this.pipelineSyncTaskInterval = interval;
   }
 
   @Config(key = "missingcontainer.interval",
@@ -56,14 +56,14 @@ public class ReconTaskConfig {
           "unhealthy containers in the cluster as reported " +
           "by Datanodes."
   )
-  private long missingContainerTaskInterval = Duration.ofMinutes(5).toMillis();
+  private Duration missingContainerTaskInterval = Duration.ofMinutes(5);
 
   public Duration getMissingContainerTaskInterval() {
-    return Duration.ofMillis(missingContainerTaskInterval);
+    return missingContainerTaskInterval;
   }
 
   public void setMissingContainerTaskInterval(Duration interval) {
-    this.missingContainerTaskInterval = interval.toMillis();
+    this.missingContainerTaskInterval = interval;
   }
 
   @Config(key = "safemode.wait.threshold",
@@ -74,14 +74,14 @@ public class ReconTaskConfig {
           "health task and pipeline sync task before recon " +
           "exits out of safe or warmup mode. "
   )
-  private long safeModeWaitThreshold = Duration.ofMinutes(5).toMillis();
+  private Duration safeModeWaitThreshold = Duration.ofMinutes(5);
 
   public Duration getSafeModeWaitThreshold() {
-    return Duration.ofMillis(safeModeWaitThreshold);
+    return safeModeWaitThreshold;
   }
 
   public void setSafeModeWaitThreshold(Duration safeModeWaitThreshold) {
-    this.safeModeWaitThreshold = safeModeWaitThreshold.toMillis();
+    this.safeModeWaitThreshold = safeModeWaitThreshold;
   }
 
   @Config(key = "containercounttask.interval",
@@ -91,15 +91,14 @@ public class ReconTaskConfig {
       description = "The time interval to wait between each runs of " +
           "container count task."
   )
-  private long containerSizeCountTaskInterval =
-      Duration.ofMinutes(1).toMillis();
+  private Duration containerSizeCountTaskInterval = Duration.ofMinutes(1);
 
   public Duration getContainerSizeCountTaskInterval() {
-    return Duration.ofMillis(containerSizeCountTaskInterval);
+    return containerSizeCountTaskInterval;
   }
 
   public void setContainerSizeCountTaskInterval(Duration interval) {
-    this.containerSizeCountTaskInterval = interval.toMillis();
+    this.containerSizeCountTaskInterval = interval;
   }
 
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to