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 <ekaterina.dimitr...@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-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org