You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ed...@apache.org on 2022/02/06 03:44:18 UTC

[cassandra] 05/13: Extend DurationSpec and DataStorageSpec for smallest unit and transfer denylist parameters to the new framework patch by Ekaterina Dimitrova; reviewed by Caleb Rackliffe, David Capwell, Michael Semb Wever and Benjamin Lerer for CASSANDRA-15234

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

edimitrova pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit b9e2ab75f8f6dedd45c6ad7a83b3160149869262
Author: Ekaterina Dimitrova <ek...@datastax.com>
AuthorDate: Wed Feb 2 12:47:41 2022 -0500

    Extend DurationSpec and DataStorageSpec for smallest unit and transfer denylist parameters to the new framework
    patch by Ekaterina Dimitrova; reviewed by Caleb Rackliffe, David Capwell, Michael Semb Wever and Benjamin Lerer for CASSANDRA-15234
---
 conf/cassandra.yaml                                | 14 ++--
 src/java/org/apache/cassandra/config/Config.java   | 12 ++--
 .../org/apache/cassandra/config/Converters.java    | 28 ++++----
 .../apache/cassandra/config/DataStorageSpec.java   | 49 ++++++++++++--
 .../cassandra/config/DatabaseDescriptor.java       | 46 ++++++-------
 .../org/apache/cassandra/config/DurationSpec.java  | 75 +++++++++++++++++-----
 .../config/SmallestDataStorageKibibytes.java       | 55 ++++++++++++++++
 .../config/SmallestDataStorageMebibytes.java       | 55 ++++++++++++++++
 .../config/SmallestDurationMilliseconds.java       | 57 ++++++++++++++++
 .../cassandra/config/SmallestDurationMinutes.java  | 57 ++++++++++++++++
 .../cassandra/config/SmallestDurationSeconds.java  | 57 ++++++++++++++++
 .../apache/cassandra/schema/PartitionDenylist.java |  6 +-
 .../org/apache/cassandra/service/StorageProxy.java | 16 ++---
 .../distributed/test/PartitionDenylistTest.java    |  8 +--
 .../config/DatabaseDescriptorRefTest.java          |  7 +-
 .../cassandra/config/DatabaseDescriptorTest.java   |  4 +-
 .../LoadOldYAMLBackwardCompatibilityTest.java      |  6 +-
 .../config/SmallestDataStorageKibibytesTest.java   | 42 ++++++++++++
 .../config/SmallestDataStorageMebibytesTest.java   | 42 ++++++++++++
 .../config/SmallestDurationMillisecondsTest.java   | 48 ++++++++++++++
 .../config/SmallestDurationMinutesTest.java        | 52 +++++++++++++++
 .../config/SmallestDurationSecondsTest.java        | 50 +++++++++++++++
 .../cassandra/service/PartitionDenylistTest.java   |  8 +--
 23 files changed, 701 insertions(+), 93 deletions(-)

diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index 265bf38..1d7998a 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -841,7 +841,7 @@ rpc_keepalive: true
 # Uncomment to set socket buffer size for internode communication
 # Note that when setting this, the buffer size is limited by net.core.wmem_max
 # and when not setting it it is defined by net.ipv4.tcp_wmem
-# internode_socket_receive_buffer_size_in_bytes:
+# internode_socket_receive_buffer_size:
 
 # Set to true to have Cassandra create a hard link to each sstable
 # flushed or streamed locally in a backups/ subdirectory of the
@@ -1076,19 +1076,19 @@ slow_query_log_timeout_in_ms: 500
 
 # Allows denying configurable access (rw/rr) to operations on configured ks, table, and partitions, intended for use by
 # operators to manage cluster health vs application access. See CASSANDRA-12106 and CEP-13 for more details.
-# enable_partition_denylist: false
+# partition_denylist_enabled: false
 
-# enable_denylist_writes: true
-# enable_denylist_reads: true
-# enable_denylist_range_reads: true
+# denylist_writes_enabled: true
+# denylist_reads_enabled: true
+# denylist_range_reads_enabled: true
 
 # The interval at which keys in the cache for denylisting will "expire" and async refresh from the backing DB.
 # Note: this serves only as a fail-safe, as the usage pattern is expected to be "mutate state, refresh cache" on any
 # changes to the underlying denylist entries. See documentation for details.
-# denylist_refresh_seconds: 600
+# denylist_refresh: 600s
 
 # In the event of errors on attempting to load the denylist cache, retry on this interval.
-# denylist_initial_load_retry_seconds: 5
+# denylist_initial_load_retry: 5s
 
 # We cap the number of denylisted keys allowed per table to keep things from growing unbounded. Nodes will warn above
 # this limit while allowing new denylisted keys to be inserted. Denied keys are loaded in natural query / clustering
diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java
index 0485cc1..eb67be1 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -546,17 +546,17 @@ public class Config
     /** This feature allows denying access to operations on certain key partitions, intended for use by operators to
      * provide another tool to manage cluster health vs application access. See CASSANDRA-12106 and CEP-13 for more details.
      */
-    public volatile boolean enable_partition_denylist = false;
+    public volatile boolean partition_denylist_enabled = false;
 
-    public volatile boolean enable_denylist_writes = true;
+    public volatile boolean denylist_writes_enabled = true;
 
-    public volatile boolean enable_denylist_reads = true;
+    public volatile boolean denylist_reads_enabled = true;
 
-    public volatile boolean enable_denylist_range_reads = true;
+    public volatile boolean denylist_range_reads_enabled = true;
 
-    public int denylist_refresh_seconds = 600;
+    public SmallestDurationSeconds denylist_refresh = new SmallestDurationSeconds("600s");
 
-    public int denylist_initial_load_retry_seconds = 5;
+    public SmallestDurationSeconds denylist_initial_load_retry = new SmallestDurationSeconds("5s");
 
     /** We cap the number of denylisted keys allowed per table to keep things from growing unbounded. Operators will
      * receive warnings and only denylist_max_keys_per_table in natural query ordering will be processed on overflow.
diff --git a/src/java/org/apache/cassandra/config/Converters.java b/src/java/org/apache/cassandra/config/Converters.java
index 629e3d3..eb64552 100644
--- a/src/java/org/apache/cassandra/config/Converters.java
+++ b/src/java/org/apache/cassandra/config/Converters.java
@@ -36,30 +36,30 @@ public enum Converters
      */
     IDENTITY(null, o -> o, o-> o),
     MILLIS_DURATION(Long.class,
-                    o -> DurationSpec.inMilliseconds((Long) o),
-                    o -> ((DurationSpec)o).toMilliseconds()),
+                    o -> SmallestDurationMilliseconds.inMilliseconds((Long) o),
+                    o -> ((SmallestDurationMilliseconds)o).toMilliseconds()),
     MILLIS_DOUBLE_DURATION(Double.class,
-                           o ->  DurationSpec.inDoubleMilliseconds((Double) o),
-                           o -> ((DurationSpec)o).toMilliseconds()),
+                           o ->  SmallestDurationMilliseconds.inDoubleMilliseconds((Double) o),
+                           o -> ((SmallestDurationMilliseconds)o).toMilliseconds()),
     /**
      * This converter is used to support backward compatibility for parameters where in the past -1 was used as a value
      * Example: credentials_update_interval_in_ms = -1 and credentials_update_interval = null (quantity of 0ms) are equal.
      */
     MILLIS_CUSTOM_DURATION(Long.class,
-                           o -> (Long)o == -1 ? new DurationSpec("0ms") : DurationSpec.inMilliseconds((Long) o),
-                           o -> ((DurationSpec)o).toMilliseconds() == 0 ? -1 : ((DurationSpec)o).toMilliseconds()),
+                           o -> (Long)o == -1 ? new SmallestDurationMilliseconds("0ms") : SmallestDurationMilliseconds.inMilliseconds((Long) o),
+                           o -> ((SmallestDurationMilliseconds)o).toMilliseconds() == 0 ? -1 : ((SmallestDurationMilliseconds)o).toMilliseconds()),
     SECONDS_DURATION(Long.class,
-                     o -> DurationSpec.inSeconds((Long) o),
-                     o -> ((DurationSpec)o).toSeconds()),
+                     o -> SmallestDurationSeconds.inSeconds((Long) o),
+                     o -> ((SmallestDurationSeconds)o).toSeconds()),
     MINUTES_DURATION(Long.class,
-                     o -> DurationSpec.inMinutes((Long) o),
-                     o -> ((DurationSpec)o).toMinutes()),
+                     o -> SmallestDurationMinutes.inMinutes((Long) o),
+                     o -> ((SmallestDurationMinutes)o).toMinutes()),
     MEBIBYTES_DATA_STORAGE(Long.class,
-                          o -> DataStorageSpec.inMebibytes((Long) o),
-                          o -> ((DataStorageSpec)o).toMebibytes()),
+                          o -> SmallestDataStorageMebibytes.inMebibytes((Long) o),
+                          o -> ((SmallestDataStorageMebibytes)o).toMebibytes()),
     KIBIBYTES_DATASTORAGE(Long.class,
-                          o -> DataStorageSpec.inKibibytes((Long) o),
-                          o -> ((DataStorageSpec)o).toKibibytes()),
+                          o -> SmallestDataStorageKibibytes.inKibibytes((Long) o),
+                          o -> ((SmallestDataStorageKibibytes)o).toKibibytes()),
     BYTES_DATASTORAGE(Long.class,
                       o -> DataStorageSpec.inBytes((Long) o),
                       o -> ((DataStorageSpec)o).toBytes()),
diff --git a/src/java/org/apache/cassandra/config/DataStorageSpec.java b/src/java/org/apache/cassandra/config/DataStorageSpec.java
index 72ed2ba..baa6d4a 100644
--- a/src/java/org/apache/cassandra/config/DataStorageSpec.java
+++ b/src/java/org/apache/cassandra/config/DataStorageSpec.java
@@ -23,18 +23,30 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.primitives.Ints;
 
 import org.apache.cassandra.exceptions.ConfigurationException;
 
+import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.GIBIBYTES;
+import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
+import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES;
+
 /**
  * Represents an amount of data storage. Wrapper class for Cassandra configuration parameters, providing to the
  * users the opportunity to be able to provide config with a unit of their choice in cassandra.yaml as per the available
  * options. (CASSANDRA-15234)
  */
-public final class DataStorageSpec
+public class DataStorageSpec
 {
     /**
+     * Immutable map that matches supported time units according to a provided smallest supported time unit
+     */
+    private static final ImmutableMap<DataStorageUnit, ImmutableSet<DataStorageUnit>> MAP_UNITS_PER_MIN_UNIT =
+    ImmutableMap.of(KIBIBYTES, ImmutableSet.of(KIBIBYTES, MEBIBYTES, GIBIBYTES),
+                    MEBIBYTES, ImmutableSet.of(MEBIBYTES, GIBIBYTES));
+    /**
      * The Regexp used to parse the storage provided as String.
      */
     private static final Pattern STORAGE_UNITS_PATTERN = Pattern.compile("^(\\d+)(GiB|MiB|KiB|B)$");
@@ -48,7 +60,7 @@ public final class DataStorageSpec
         if (value == null || value.equals("null"))
         {
             quantity = 0;
-            unit = DataStorageUnit.MEBIBYTES; // the unit doesn't really matter as 0 is 0 in all units
+            unit = MEBIBYTES; // the unit doesn't really matter as 0 is 0 in all units
             return;
         }
 
@@ -74,6 +86,35 @@ public final class DataStorageSpec
         this.unit = unit;
     }
 
+    public DataStorageSpec (String value, DataStorageUnit minUnit)
+    {
+        if (value == null || value.equals("null"))
+        {
+            quantity = 0;
+            unit = minUnit;
+            return;
+        }
+
+        if (!MAP_UNITS_PER_MIN_UNIT.containsKey(minUnit))
+            throw new ConfigurationException("Invalid smallest unit set for " + value);
+
+        //parse the string field value
+        Matcher matcher = STORAGE_UNITS_PATTERN.matcher(value);
+
+        if (matcher.find())
+        {
+            quantity = Long.parseLong(matcher.group(1));
+            unit = DataStorageUnit.fromSymbol(matcher.group(2));
+
+            if (!MAP_UNITS_PER_MIN_UNIT.get(minUnit).contains(unit))
+                throw new ConfigurationException("Invalid data storage: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT);
+        }
+        else
+        {
+            throw new ConfigurationException("Invalid data storage: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit) +
+                                             " where case matters and only non-negative values are accepted");
+        }
+    }
     /**
      * Creates a {@code DataStorageSpec} of the specified amount of bytes.
      *
@@ -93,7 +134,7 @@ public final class DataStorageSpec
      */
     public static DataStorageSpec inKibibytes(long kibibytes)
     {
-        return new DataStorageSpec(kibibytes, DataStorageUnit.KIBIBYTES);
+        return new DataStorageSpec(kibibytes, KIBIBYTES);
     }
 
     /**
@@ -104,7 +145,7 @@ public final class DataStorageSpec
      */
     public static DataStorageSpec inMebibytes(long mebibytes)
     {
-        return new DataStorageSpec(mebibytes, DataStorageUnit.MEBIBYTES);
+        return new DataStorageSpec(mebibytes, MEBIBYTES);
     }
 
     /**
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 622a825..102a587 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -3609,68 +3609,70 @@ public class DatabaseDescriptor
         conf.consecutive_message_errors_threshold = value;
     }
 
-    public static boolean getEnablePartitionDenylist()
+    public static boolean getPartitionDenylistEnabled()
     {
-        return conf.enable_partition_denylist;
+        return conf.partition_denylist_enabled;
     }
 
-    public static void setEnablePartitionDenylist(boolean enabled)
+    public static void setPartitionDenylistEnabled(boolean enabled)
     {
-        conf.enable_partition_denylist = enabled;
+        conf.partition_denylist_enabled = enabled;
     }
 
-    public static boolean getEnableDenylistWrites()
+    public static boolean getDenylistWritesEnabled()
     {
-        return conf.enable_denylist_writes;
+        return conf.denylist_writes_enabled;
     }
 
-    public static void setEnableDenylistWrites(boolean enabled)
+    public static void setDenylistWritesEnabled(boolean enabled)
     {
-        conf.enable_denylist_writes = enabled;
+        conf.denylist_writes_enabled = enabled;
     }
 
-    public static boolean getEnableDenylistReads()
+    public static boolean getDenylistReadsEnabled()
     {
-        return conf.enable_denylist_reads;
+        return conf.denylist_reads_enabled;
     }
 
-    public static void setEnableDenylistReads(boolean enabled)
+    public static void setDenylistReadsEnabled(boolean enabled)
     {
-        conf.enable_denylist_reads = enabled;
+        conf.denylist_reads_enabled = enabled;
     }
 
-    public static boolean getEnableDenylistRangeReads()
+    public static boolean getDenylistRangeReadsEnabled()
     {
-        return conf.enable_denylist_range_reads;
+        return conf.denylist_range_reads_enabled;
     }
 
-    public static void setEnableDenylistRangeReads(boolean enabled)
+    public static void setDenylistRangeReadsEnabled(boolean enabled)
     {
-        conf.enable_denylist_range_reads = enabled;
+        conf.denylist_range_reads_enabled = enabled;
     }
 
     public static int getDenylistRefreshSeconds()
     {
-        return conf.denylist_refresh_seconds;
+        return conf.denylist_refresh.toSecondsAsInt();
     }
 
     public static void setDenylistRefreshSeconds(int seconds)
     {
         if (seconds <= 0)
-            throw new IllegalArgumentException("denylist_refresh_seconds must be a positive integer.");
-        conf.denylist_refresh_seconds = seconds;
+            throw new IllegalArgumentException("denylist_refresh must be a positive integer.");
+
+        conf.denylist_refresh = SmallestDurationSeconds.inSeconds(seconds);
     }
 
     public static int getDenylistInitialLoadRetrySeconds()
     {
-        return conf.denylist_initial_load_retry_seconds;
+        return conf.denylist_initial_load_retry.toSecondsAsInt();
     }
 
     public static void setDenylistInitialLoadRetrySeconds(int seconds)
     {
         if (seconds <= 0)
-            throw new IllegalArgumentException("denylist_initial_load_retry_seconds must be a positive integer.");
-        conf.denylist_initial_load_retry_seconds = seconds;
+            throw new IllegalArgumentException("denylist_initial_load_retry must be a positive integer.");
+
+        conf.denylist_initial_load_retry = SmallestDurationSeconds.inSeconds(seconds);
     }
 
     public static ConsistencyLevel getDenylistConsistencyLevel()
diff --git a/src/java/org/apache/cassandra/config/DurationSpec.java b/src/java/org/apache/cassandra/config/DurationSpec.java
index 796fde6..f06c247 100644
--- a/src/java/org/apache/cassandra/config/DurationSpec.java
+++ b/src/java/org/apache/cassandra/config/DurationSpec.java
@@ -25,24 +25,40 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.primitives.Ints;
 
 import org.apache.cassandra.exceptions.ConfigurationException;
 
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
 /**
  * Represents a positive time duration. Wrapper class for Cassandra duration configuration parameters, providing to the
  * users the opportunity to be able to provide config with a unit of their choice in cassandra.yaml as per the available
  * options. (CASSANDRA-15234)
  */
-public final class DurationSpec
+public class DurationSpec
 {
     /**
+     * Immutable map that matches supported time units according to a provided smallest supported time unit
+     */
+    private static final ImmutableMap<TimeUnit, ImmutableSet<TimeUnit>> MAP_UNITS_PER_MIN_UNIT =
+    ImmutableMap.of(MILLISECONDS, ImmutableSet.of(MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS),
+                    SECONDS, ImmutableSet.of(SECONDS, MINUTES, HOURS, DAYS),
+                    MINUTES, ImmutableSet.of(MINUTES, HOURS, DAYS));
+    /**
      * The Regexp used to parse the duration provided as String.
      */
-    private static final Pattern TIME_UNITS_PATTERN = Pattern.compile(("^(\\d+)(d|h|s|ms|us|µs|ns|m)"));
+    private static final Pattern TIME_UNITS_PATTERN = Pattern.compile(("^(\\d+)(d|h|s|ms|us|µs|ns|m)$"));
+
     private static final Pattern VALUES_PATTERN = Pattern.compile(("\\d+"));
 
-    public final long quantity;
+    private final long quantity;
 
     private final TimeUnit unit;
 
@@ -51,7 +67,7 @@ public final class DurationSpec
         if (value == null || value.equals("null") || value.toLowerCase(Locale.ROOT).equals("nan"))
         {
             quantity = 0;
-            unit = TimeUnit.MILLISECONDS;
+            unit = MILLISECONDS;
             return;
         }
 
@@ -84,6 +100,35 @@ public final class DurationSpec
         this(Math.round(quantity), unit);
     }
 
+    public DurationSpec(String value, TimeUnit minUnit)
+    {
+        if (value == null || value.equals("null") || value.toLowerCase(Locale.ROOT).equals("nan"))
+        {
+            quantity = 0;
+            unit = minUnit;
+            return;
+        }
+
+        if (!MAP_UNITS_PER_MIN_UNIT.containsKey(minUnit))
+            throw new ConfigurationException("Invalid smallest unit set for " + value);
+
+        Matcher matcher = TIME_UNITS_PATTERN.matcher(value);
+
+        if(matcher.find())
+        {
+            quantity = Long.parseLong(matcher.group(1));
+            unit = fromSymbol(matcher.group(2));
+
+            if (!MAP_UNITS_PER_MIN_UNIT.get(minUnit).contains(unit))
+                throw new ConfigurationException("Invalid duration: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit));
+        }
+        else
+        {
+            throw new ConfigurationException("Invalid duration: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit) +
+                                             " where case matters and only non-negative values.");
+        }
+    }
+
     /**
      * Creates a {@code DurationSpec} of the specified amount of milliseconds.
      *
@@ -92,12 +137,12 @@ public final class DurationSpec
      */
     public static DurationSpec inMilliseconds(long milliseconds)
     {
-        return new DurationSpec(milliseconds, TimeUnit.MILLISECONDS);
+        return new DurationSpec(milliseconds, MILLISECONDS);
     }
 
     public static DurationSpec inDoubleMilliseconds(double milliseconds)
     {
-        return new DurationSpec(milliseconds, TimeUnit.MILLISECONDS);
+        return new DurationSpec(milliseconds, MILLISECONDS);
     }
 
     /**
@@ -108,7 +153,7 @@ public final class DurationSpec
      */
     public static DurationSpec inSeconds(long seconds)
     {
-        return new DurationSpec(seconds, TimeUnit.SECONDS);
+        return new DurationSpec(seconds, SECONDS);
     }
 
     /**
@@ -119,7 +164,7 @@ public final class DurationSpec
      */
     public static DurationSpec inMinutes(long minutes)
     {
-        return new DurationSpec(minutes, TimeUnit.MINUTES);
+        return new DurationSpec(minutes, MINUTES);
     }
 
     /**
@@ -130,7 +175,7 @@ public final class DurationSpec
      */
     public static DurationSpec inHours(long hours)
     {
-        return new DurationSpec(hours, TimeUnit.HOURS);
+        return new DurationSpec(hours, HOURS);
     }
 
     /**
@@ -151,7 +196,7 @@ public final class DurationSpec
         if (matcher.matches())
         {
             seconds = Long.parseLong(value);
-            return new DurationSpec(seconds, TimeUnit.SECONDS);
+            return new DurationSpec(seconds, SECONDS);
         }
 
         //otherwise we just use the standard constructors
@@ -166,11 +211,11 @@ public final class DurationSpec
     {
         switch (symbol.toLowerCase())
         {
-            case "d": return TimeUnit.DAYS;
-            case "h": return TimeUnit.HOURS;
-            case "m": return TimeUnit.MINUTES;
-            case "s": return TimeUnit.SECONDS;
-            case "ms": return TimeUnit.MILLISECONDS;
+            case "d": return DAYS;
+            case "h": return HOURS;
+            case "m": return MINUTES;
+            case "s": return SECONDS;
+            case "ms": return MILLISECONDS;
             case "us":
             case "µs": return TimeUnit.MICROSECONDS;
             case "ns": return TimeUnit.NANOSECONDS;
diff --git a/src/java/org/apache/cassandra/config/SmallestDataStorageKibibytes.java b/src/java/org/apache/cassandra/config/SmallestDataStorageKibibytes.java
new file mode 100644
index 0000000..e298ba5
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/SmallestDataStorageKibibytes.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+/**
+ * Wrapper class for Cassandra data storage configuration parameters which are internally represented in Kibibytes. In order
+ * not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
+ * supported unit) we restrict those parameters to use only kibibytes or larger units. (CASSANDRA-15234)
+ */
+public class SmallestDataStorageKibibytes extends DataStorageSpec
+{
+    /**
+     * Creates a {@code SmallestDataStorageKibibytes} of the specified amount of seconds and provides the smallest
+     * required unit of Kibibytes for the respective parameter of type {@code SmallestDurationSeconds}.
+     *
+     * @param value the data storage
+     *
+     */
+    public SmallestDataStorageKibibytes(String value)
+    {
+        super(value, DataStorageSpec.DataStorageUnit.KIBIBYTES);
+    }
+
+    private SmallestDataStorageKibibytes(long quantity, DataStorageSpec.DataStorageUnit unit)
+    {
+        super(quantity, unit);
+    }
+
+    /**
+     * Creates a {@code SmallestDataStorageKibibytes} of the specified amount of kibibytes.
+     *
+     * @param kibibytes the amount of kibibytes
+     * @return a data storage
+     */
+    public static SmallestDataStorageKibibytes inKibibytes(long kibibytes)
+    {
+        return new SmallestDataStorageKibibytes(kibibytes, DataStorageSpec.DataStorageUnit.KIBIBYTES);
+    }
+}
diff --git a/src/java/org/apache/cassandra/config/SmallestDataStorageMebibytes.java b/src/java/org/apache/cassandra/config/SmallestDataStorageMebibytes.java
new file mode 100644
index 0000000..effc9a8
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/SmallestDataStorageMebibytes.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+/**
+ * Wrapper class for Cassandra data storage configuration parameters which are internally represented in mebibytes. In order
+ * not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
+ * supported unit) we restrict those parameters to use only mebibytes or larger units. (CASSANDRA-15234)
+ */
+public class SmallestDataStorageMebibytes extends DataStorageSpec
+{
+    /**
+     * Creates a {@code SmallestDataStoragemebibytes} of the specified amount of seconds and provides the smallest
+     * required unit of mebibytes for the respective parameter of type {@code SmallestDurationSeconds}.
+     *
+     * @param value the data storage
+     *
+     */
+    public SmallestDataStorageMebibytes(String value)
+    {
+        super(value, DataStorageSpec.DataStorageUnit.MEBIBYTES);
+    }
+
+    private SmallestDataStorageMebibytes(long quantity, DataStorageSpec.DataStorageUnit unit)
+    {
+        super(quantity, unit);
+    }
+
+    /**
+     * Creates a {@code SmallestDataStorageMebibytes} of the specified amount of mebibytes.
+     *
+     * @param mebibytes the amount of mebibytes
+     * @return a data storage
+     */
+    public static SmallestDataStorageMebibytes inMebibytes(long mebibytes)
+    {
+        return new SmallestDataStorageMebibytes(mebibytes, DataStorageSpec.DataStorageUnit.MEBIBYTES);
+    }
+}
diff --git a/src/java/org/apache/cassandra/config/SmallestDurationMilliseconds.java b/src/java/org/apache/cassandra/config/SmallestDurationMilliseconds.java
new file mode 100644
index 0000000..cf6ef1b
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/SmallestDurationMilliseconds.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wrapper class for Cassandra duration configuration parameters which are internally represented in Milliseconds. In order
+ * not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
+ * supported unit) we restrict those parameters to use only Milliseconds or larger units. (CASSANDRA-15234)
+ */
+public class SmallestDurationMilliseconds extends DurationSpec
+{
+    /**
+     * Creates a {@code SmallestDurationMilliseconds} of the specified amount of milliseconds and provides the smallest
+     * required unit of milliseconds for the respective parameter of type {@code SmallestDurationMilliseconds}.
+     *
+     * @param value the duration
+     *
+     */
+    public SmallestDurationMilliseconds(String value)
+    {
+        super(value, TimeUnit.MILLISECONDS);
+    }
+
+    private SmallestDurationMilliseconds(long quantity, TimeUnit unit)
+    {
+        super(quantity, unit);
+    }
+
+    /**
+     * Creates a {@code SmallestDurationMilliseconds} of the specified amount of milliseconds.
+     *
+     * @param milliseconds the amount of milliseconds
+     * @return a duration
+     */
+    public static SmallestDurationMilliseconds inMilliseconds(long milliseconds)
+    {
+        return new SmallestDurationMilliseconds(milliseconds, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/src/java/org/apache/cassandra/config/SmallestDurationMinutes.java b/src/java/org/apache/cassandra/config/SmallestDurationMinutes.java
new file mode 100644
index 0000000..d68230f
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/SmallestDurationMinutes.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wrapper class for Cassandra duration configuration parameters which are internally represented in Minuts. In order
+ * not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
+ * supported unit) we restrict those parameters to use only Minutes or larger units. (CASSANDRA-15234)
+ */
+public class SmallestDurationMinutes extends DurationSpec
+{
+    /**
+     * Creates a {@code SmallestDurationMinutes} of the specified amount of minutes and provides the smallest
+     * required unit of minutes for the respective parameter of type {@code SmallestDurationMinutes}.
+     *
+     * @param value the duration
+     *
+     */
+    public SmallestDurationMinutes(String value)
+    {
+        super(value, TimeUnit.MINUTES);
+    }
+
+    private SmallestDurationMinutes(long quantity, TimeUnit unit)
+    {
+        super(quantity, unit);
+    }
+
+    /**
+     * Creates a {@code SmallestDurationMinutes} of the specified amount of minutes.
+     *
+     * @param minutes the amount of minutes
+     * @return a duration
+     */
+    public static SmallestDurationMinutes inMinutes(long minutes)
+    {
+        return new SmallestDurationMinutes(minutes, TimeUnit.MINUTES);
+    }
+}
diff --git a/src/java/org/apache/cassandra/config/SmallestDurationSeconds.java b/src/java/org/apache/cassandra/config/SmallestDurationSeconds.java
new file mode 100644
index 0000000..6ca8266
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/SmallestDurationSeconds.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wrapper class for Cassandra duration configuration parameters which are internally represented in Seconds. In order
+ * not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
+ * supported unit) we restrict those parameters to use only Seconds or larger units. (CASSANDRA-15234)
+ */
+public class SmallestDurationSeconds extends DurationSpec
+{
+    /**
+     * Creates a {@code SmallestDurationSeconds} of the specified amount of seconds and provides the smallest
+     * required unit of seconds for the respective parameter of type {@code SmallestDurationSeconds}.
+     *
+     * @param value the duration
+     *
+     */
+    public SmallestDurationSeconds(String value)
+    {
+        super(value, TimeUnit.SECONDS);
+    }
+
+    private SmallestDurationSeconds(long quantity, TimeUnit unit)
+    {
+        super(quantity, unit);
+    }
+
+    /**
+     * Creates a {@code SmallestDurationSeconds} of the specified amount of seconds.
+     *
+     * @param seconds the amount of seconds
+     * @return a duration
+     */
+    public static SmallestDurationSeconds inSeconds(long seconds)
+    {
+        return new SmallestDurationSeconds(seconds, TimeUnit.SECONDS);
+    }
+}
diff --git a/src/java/org/apache/cassandra/schema/PartitionDenylist.java b/src/java/org/apache/cassandra/schema/PartitionDenylist.java
index c9aee97..9bd171c 100644
--- a/src/java/org/apache/cassandra/schema/PartitionDenylist.java
+++ b/src/java/org/apache/cassandra/schema/PartitionDenylist.java
@@ -131,7 +131,7 @@ public class PartitionDenylist
      */
     public void initialLoad()
     {
-        if (!DatabaseDescriptor.getEnablePartitionDenylist())
+        if (!DatabaseDescriptor.getPartitionDenylistEnabled())
             return;
 
         synchronized (this)
@@ -309,7 +309,7 @@ public class PartitionDenylist
         final TableMetadata tmd = Schema.instance.getTableMetadata(tid);
 
         // We have a few quick state checks to get out of the way first; this is hot path so we want to do these first if possible.
-        if (!DatabaseDescriptor.getEnablePartitionDenylist() || tid == null || tmd == null || !canDenylistKeyspace(tmd.keyspace))
+        if (!DatabaseDescriptor.getPartitionDenylistEnabled() || tid == null || tmd == null || !canDenylistKeyspace(tmd.keyspace))
             return true;
 
         try
@@ -351,7 +351,7 @@ public class PartitionDenylist
     public int getDeniedKeysInRangeCount(final TableId tid, final AbstractBounds<PartitionPosition> range)
     {
         final TableMetadata tmd = Schema.instance.getTableMetadata(tid);
-        if (!DatabaseDescriptor.getEnablePartitionDenylist() || tid == null || tmd == null || !canDenylistKeyspace(tmd.keyspace))
+        if (!DatabaseDescriptor.getPartitionDenylistEnabled() || tid == null || tmd == null || !canDenylistKeyspace(tmd.keyspace))
             return 0;
 
         try
diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java
index e273348..686192c 100644
--- a/src/java/org/apache/cassandra/service/StorageProxy.java
+++ b/src/java/org/apache/cassandra/service/StorageProxy.java
@@ -287,7 +287,7 @@ public class StorageProxy implements StorageProxyMBean
         {
             TableMetadata metadata = Schema.instance.validateTable(keyspaceName, cfName);
 
-            if (DatabaseDescriptor.getEnablePartitionDenylist() && DatabaseDescriptor.getEnableDenylistWrites() && !partitionDenylist.isKeyPermitted(keyspaceName, cfName, key.getKey()))
+            if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistWritesEnabled() && !partitionDenylist.isKeyPermitted(keyspaceName, cfName, key.getKey()))
             {
                 denylistMetrics.incrementWritesRejected();
                 throw new InvalidRequestException(String.format("Unable to CAS write to denylisted partition [0x%s] in %s/%s",
@@ -1079,7 +1079,7 @@ public class StorageProxy implements StorageProxyMBean
                                           long queryStartNanoTime)
     throws WriteTimeoutException, WriteFailureException, UnavailableException, OverloadedException, InvalidRequestException
     {
-        if (DatabaseDescriptor.getEnablePartitionDenylist() && DatabaseDescriptor.getEnableDenylistWrites())
+        if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistWritesEnabled())
         {
             for (final IMutation mutation : mutations)
             {
@@ -1788,7 +1788,7 @@ public class StorageProxy implements StorageProxyMBean
             throw exception;
         }
 
-        if (DatabaseDescriptor.getEnablePartitionDenylist() && DatabaseDescriptor.getEnableDenylistReads())
+        if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistReadsEnabled())
         {
             for (SinglePartitionReadCommand command : group.queries)
             {
@@ -2143,7 +2143,7 @@ public class StorageProxy implements StorageProxyMBean
                                                   ConsistencyLevel consistencyLevel,
                                                   long queryStartNanoTime)
     {
-        if (DatabaseDescriptor.getEnablePartitionDenylist() && DatabaseDescriptor.getEnableDenylistRangeReads())
+        if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistRangeReadsEnabled())
         {
             final int denylisted = partitionDenylist.getDeniedKeysInRangeCount(command.metadata().id, command.dataRange().keyRange());
             if (denylisted > 0)
@@ -2877,25 +2877,25 @@ public class StorageProxy implements StorageProxyMBean
     @Override
     public void setEnablePartitionDenylist(boolean enabled)
     {
-        DatabaseDescriptor.setEnablePartitionDenylist(enabled);
+        DatabaseDescriptor.setPartitionDenylistEnabled(enabled);
     }
 
     @Override
     public void setEnableDenylistWrites(boolean enabled)
     {
-        DatabaseDescriptor.setEnableDenylistWrites(enabled);
+        DatabaseDescriptor.setDenylistWritesEnabled(enabled);
     }
 
     @Override
     public void setEnableDenylistReads(boolean enabled)
     {
-        DatabaseDescriptor.setEnableDenylistReads(enabled);
+        DatabaseDescriptor.setDenylistReadsEnabled(enabled);
     }
 
     @Override
     public void setEnableDenylistRangeReads(boolean enabled)
     {
-        DatabaseDescriptor.setEnableDenylistRangeReads(enabled);
+        DatabaseDescriptor.setDenylistRangeReadsEnabled(enabled);
     }
 
     @Override
diff --git a/test/distributed/org/apache/cassandra/distributed/test/PartitionDenylistTest.java b/test/distributed/org/apache/cassandra/distributed/test/PartitionDenylistTest.java
index 43b3ef8..382981f 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/PartitionDenylistTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/PartitionDenylistTest.java
@@ -65,8 +65,8 @@ public class PartitionDenylistTest extends TestBaseImpl
                                       .withConfig(config -> config
                                       .with(NETWORK)
                                       .with(GOSSIP)
-                                      .set("enable_partition_denylist", true)
-                                      .set("denylist_initial_load_retry_seconds", 1))
+                                      .set("partition_denylist_enabled", true)
+                                      .set("denylist_initial_load_retry", "1s"))
                                       .createWithoutStarting())
         {
             cluster.forEach(i -> {
@@ -142,8 +142,8 @@ public class PartitionDenylistTest extends TestBaseImpl
                                       .withConfig(config -> config
                                       .with(NETWORK)
                                       .with(GOSSIP)
-                                      .set("enable_partition_denylist", true)
-                                      .set("denylist_initial_load_retry_seconds", 1))
+                                      .set("partition_denylist_enabled", true)
+                                      .set("denylist_initial_load_retry", "1s"))
                                       .createWithoutStarting())
         {
             // Starting without networking enabled in the hope it doesn't trigger
diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
index dd98509..b586245 100644
--- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
+++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
@@ -210,7 +210,12 @@ public class DatabaseDescriptorRefTest
     "org.apache.cassandra.config.DataRateSpec$DataRateUnit",
     "org.apache.cassandra.config.DataRateSpec$DataRateUnit$1",
     "org.apache.cassandra.config.DataRateSpec$DataRateUnit$2",
-    "org.apache.cassandra.config.DataRateSpec$DataRateUnit$3"
+    "org.apache.cassandra.config.DataRateSpec$DataRateUnit$3",
+    "org.apache.cassandra.config.SmallestDurationMinutes",
+    "org.apache.cassandra.config.SmallestDurationSeconds",
+    "org.apache.cassandra.config.SmallestDurationMilliseconds",
+    "org.apache.cassandra.config.SmallestDataStorageKibibytes",
+    "org.apache.cassandra.config.SmallestDataStorageMebibytes"
     };
 
     static final Set<String> checkedClasses = new HashSet<>(Arrays.asList(validClasses));
diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
index d389a6c..4af1f8a 100644
--- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
+++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
@@ -599,8 +599,8 @@ public class DatabaseDescriptorTest
     {
         DatabaseDescriptor.loadConfig();
 
-        expectIllegalArgumentException(DatabaseDescriptor::setDenylistRefreshSeconds, 0, "denylist_refresh_seconds must be a positive integer.");
-        expectIllegalArgumentException(DatabaseDescriptor::setDenylistRefreshSeconds, -1, "denylist_refresh_seconds must be a positive integer.");
+        expectIllegalArgumentException(DatabaseDescriptor::setDenylistRefreshSeconds, 0, "denylist_refresh must be a positive integer.");
+        expectIllegalArgumentException(DatabaseDescriptor::setDenylistRefreshSeconds, -1, "denylist_refresh must be a positive integer.");
         expectIllegalArgumentException(DatabaseDescriptor::setDenylistMaxKeysPerTable, 0, "denylist_max_keys_per_table must be a positive integer.");
         expectIllegalArgumentException(DatabaseDescriptor::setDenylistMaxKeysPerTable, -1, "denylist_max_keys_per_table must be a positive integer.");
         expectIllegalArgumentException(DatabaseDescriptor::setDenylistMaxKeysTotal, 0, "denylist_max_keys_total must be a positive integer.");
diff --git a/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java b/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
index 18eaded..e1169e0 100644
--- a/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
+++ b/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
@@ -110,16 +110,16 @@ public class LoadOldYAMLBackwardCompatibilityTest
         assertTrue(config.sasi_indexes_enabled);
         assertTrue(config.drop_compact_storage_enabled);
         assertTrue(config.user_defined_functions_threads_enabled);
-        /*assertEquals(DurationSpec.inMilliseconds(2000), config.permissions_validity);
+        assertEquals(DurationSpec.inMilliseconds(2000), config.permissions_validity);
         assertEquals(DurationSpec.inMilliseconds(0), config.permissions_update_interval);
         assertEquals(DurationSpec.inMilliseconds(2000), config.roles_validity);
         assertEquals(DurationSpec.inMilliseconds(0), config.roles_update_interval);
         assertEquals(DurationSpec.inMilliseconds(2000), config.credentials_validity);
         assertEquals(DurationSpec.inMilliseconds(0), config.credentials_update_interval);
-        assertEquals(DurationSpec.inMinutes(60), config.index_summary_resize_interval);
+        //assertEquals(DurationSpec.inMinutes(60), config.index_summary_resize_interval);
 
         //parameters which names have not changed with CASSANDRA-15234
-        assertEquals(DurationSpec.inSecondsString("14400"), config.key_cache_save_period);
+        /*assertEquals(DurationSpec.inSecondsString("14400"), config.key_cache_save_period);
         assertEquals(DurationSpec.inHours(4), config.key_cache_save_period);
         assertEquals(DurationSpec.inSecondsString("0"), config.row_cache_save_period);
         assertEquals(DurationSpec.inSeconds(0), config.row_cache_save_period);
diff --git a/test/unit/org/apache/cassandra/config/SmallestDataStorageKibibytesTest.java b/test/unit/org/apache/cassandra/config/SmallestDataStorageKibibytesTest.java
new file mode 100644
index 0000000..c161d12
--- /dev/null
+++ b/test/unit/org/apache/cassandra/config/SmallestDataStorageKibibytesTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.junit.Test;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+public class SmallestDataStorageKibibytesTest
+{
+    @Test
+    public void testInvalidUnits()
+    {
+        assertThatThrownBy(() -> new SmallestDataStorageKibibytes("10B")).isInstanceOf(ConfigurationException.class)
+                                                                          .hasMessageContaining("Invalid data storage: 10B");
+    }
+
+    @Test
+    public void testValidUnits()
+    {
+        assertEquals(10L, new SmallestDataStorageKibibytes("10KiB").toKibibytes());
+    }
+}
diff --git a/test/unit/org/apache/cassandra/config/SmallestDataStorageMebibytesTest.java b/test/unit/org/apache/cassandra/config/SmallestDataStorageMebibytesTest.java
new file mode 100644
index 0000000..a313681
--- /dev/null
+++ b/test/unit/org/apache/cassandra/config/SmallestDataStorageMebibytesTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.junit.Test;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+public class SmallestDataStorageMebibytesTest
+{
+    @Test
+    public void testInvalidUnits()
+    {
+        assertThatThrownBy(() -> new SmallestDataStorageMebibytes("10B")).isInstanceOf(ConfigurationException.class)
+                                                                         .hasMessageContaining("Invalid data storage: 10B");
+    }
+
+    @Test
+    public void testValidUnits()
+    {
+        assertEquals(10L, new SmallestDataStorageMebibytes("10MiB").toMebibytes());
+    }
+}
diff --git a/test/unit/org/apache/cassandra/config/SmallestDurationMillisecondsTest.java b/test/unit/org/apache/cassandra/config/SmallestDurationMillisecondsTest.java
new file mode 100644
index 0000000..6e7597d
--- /dev/null
+++ b/test/unit/org/apache/cassandra/config/SmallestDurationMillisecondsTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.junit.Test;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+public class SmallestDurationMillisecondsTest
+{
+    @Test
+    public void testInvalidUnits()
+    {
+        assertThatThrownBy(() -> new SmallestDurationMilliseconds("10ns")).isInstanceOf(ConfigurationException.class)
+                                                                          .hasMessageContaining("Invalid duration: 10ns");
+        assertThatThrownBy(() -> new SmallestDurationMilliseconds("10us")).isInstanceOf(ConfigurationException.class)
+                                                                          .hasMessageContaining("Invalid duration: 10us");
+        assertThatThrownBy(() -> new SmallestDurationMilliseconds("10µs")).isInstanceOf(ConfigurationException.class)
+                                                                          .hasMessageContaining("Invalid duration: 10µs");
+        assertThatThrownBy(() -> new SmallestDurationMilliseconds("-10s")).isInstanceOf(ConfigurationException.class)
+                                                                          .hasMessageContaining("Invalid duration: -10s");
+    }
+
+    @Test
+    public void testValidUnits()
+    {
+        assertEquals(10L, new SmallestDurationMilliseconds("10ms").toMilliseconds());
+    }
+}
diff --git a/test/unit/org/apache/cassandra/config/SmallestDurationMinutesTest.java b/test/unit/org/apache/cassandra/config/SmallestDurationMinutesTest.java
new file mode 100644
index 0000000..68b44db
--- /dev/null
+++ b/test/unit/org/apache/cassandra/config/SmallestDurationMinutesTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.junit.Test;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+public class SmallestDurationMinutesTest
+{
+    @Test
+    public void testInvalidUnits()
+    {
+        assertThatThrownBy(() -> new SmallestDurationMinutes("10s")).isInstanceOf(ConfigurationException.class)
+                                                                    .hasMessageContaining("Invalid duration: 10s");
+        assertThatThrownBy(() -> new SmallestDurationMinutes("10ms")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10ms");
+        assertThatThrownBy(() -> new SmallestDurationMinutes("10ns")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10ns");
+        assertThatThrownBy(() -> new SmallestDurationMinutes("10us")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10us");
+        assertThatThrownBy(() -> new SmallestDurationMinutes("10µs")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10µs");
+        assertThatThrownBy(() -> new SmallestDurationMinutes("-10s")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: -10s");
+    }
+
+    @Test
+    public void testValidUnits()
+    {
+        assertEquals(10L, new SmallestDurationMinutes("10m").toMinutes());
+    }
+}
diff --git a/test/unit/org/apache/cassandra/config/SmallestDurationSecondsTest.java b/test/unit/org/apache/cassandra/config/SmallestDurationSecondsTest.java
new file mode 100644
index 0000000..c563639
--- /dev/null
+++ b/test/unit/org/apache/cassandra/config/SmallestDurationSecondsTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.junit.Test;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+public class SmallestDurationSecondsTest
+{
+    @Test
+    public void testInvalidUnits()
+    {
+        assertThatThrownBy(() -> new SmallestDurationSeconds("10ms")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10ms");
+        assertThatThrownBy(() -> new SmallestDurationSeconds("10ns")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10ns");
+        assertThatThrownBy(() -> new SmallestDurationSeconds("10us")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10us");
+        assertThatThrownBy(() -> new SmallestDurationSeconds("10µs")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: 10µs");
+        assertThatThrownBy(() -> new SmallestDurationSeconds("-10s")).isInstanceOf(ConfigurationException.class)
+                                                                     .hasMessageContaining("Invalid duration: -10s");
+    }
+
+    @Test
+    public void testValidUnits()
+    {
+        assertEquals(10L, new SmallestDurationSeconds("10s").toSeconds());
+    }
+}
diff --git a/test/unit/org/apache/cassandra/service/PartitionDenylistTest.java b/test/unit/org/apache/cassandra/service/PartitionDenylistTest.java
index 0751036..fd318cc 100644
--- a/test/unit/org/apache/cassandra/service/PartitionDenylistTest.java
+++ b/test/unit/org/apache/cassandra/service/PartitionDenylistTest.java
@@ -70,8 +70,8 @@ public class PartitionDenylistTest
                                        + "PRIMARY KEY((keyone, keytwo), keythree) ) ", ks_cql).build()
         ));
         Schema.instance.load(schema);
-        DatabaseDescriptor.setEnablePartitionDenylist(true);
-        DatabaseDescriptor.setEnableDenylistRangeReads(true);
+        DatabaseDescriptor.setPartitionDenylistEnabled(true);
+        DatabaseDescriptor.setDenylistRangeReadsEnabled(true);
         DatabaseDescriptor.setDenylistConsistencyLevel(ConsistencyLevel.ONE);
         DatabaseDescriptor.setDenylistRefreshSeconds(1);
         StorageService.instance.initServer(0);
@@ -80,7 +80,7 @@ public class PartitionDenylistTest
     @Before
     public void setup()
     {
-        DatabaseDescriptor.setEnablePartitionDenylist(true);
+        DatabaseDescriptor.setPartitionDenylistEnabled(true);
         resetDenylist();
 
         process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('aaa', 'bbb', 'ccc', 'ddd', 'v')", ConsistencyLevel.ONE);
@@ -282,7 +282,7 @@ public class PartitionDenylistTest
         process(String.format("TRUNCATE TABLE %s.table2", ks_cql), ConsistencyLevel.ONE);
         process(String.format("TRUNCATE TABLE %s.table3", ks_cql), ConsistencyLevel.ONE);
         denyAllKeys();
-        DatabaseDescriptor.setEnablePartitionDenylist(false);
+        DatabaseDescriptor.setPartitionDenylistEnabled(false);
         process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('bbb', 'ccc', 'eee', 'fff', 'w')", ConsistencyLevel.ONE);
         process("SELECT * FROM " + ks_cql + ".table1 WHERE keyone='bbb' and keytwo='ccc'", ConsistencyLevel.ONE);
         process("SELECT * FROM " + ks_cql + ".table1", ConsistencyLevel.ONE);

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org