blob: e4694b9c307ca3dbf06d1fb31c53794a76746263 [file] [log] [blame]
/*
* 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.Collections;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.cql3.statements.schema.TableAttributes;
import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.db.guardrails.Guardrails;
import org.apache.cassandra.db.guardrails.GuardrailsConfig;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.service.disk.usage.DiskUsageMonitor;
import static java.lang.String.format;
import static java.util.stream.Collectors.toSet;
/**
* Configuration settings for guardrails populated from the Yaml file.
*
* <p>Note that the settings here must only be used to build the {@link GuardrailsConfig} class and not directly by the
* code checking each guarded constraint. That code should use the higher level abstractions defined in
* {@link Guardrails}).
*
* <p>We have 2 variants of guardrails, soft (warn) and hard (fail) limits, each guardrail having either one of the
* variants or both. Note in particular that hard limits only make sense for guardrails triggering during query
* execution. For other guardrails, say one triggering during compaction, aborting that compaction does not make sense.
*
* <p>Additionally, each individual setting should have a specific value (typically -1 for numeric settings),
* that allows to disable the corresponding guardrail.
*/
public class GuardrailsOptions implements GuardrailsConfig
{
private static final Logger logger = LoggerFactory.getLogger(GuardrailsOptions.class);
private final Config config;
public GuardrailsOptions(Config config)
{
this.config = config;
validateMaxIntThreshold(config.keyspaces_warn_threshold, config.keyspaces_fail_threshold, "keyspaces");
validateMaxIntThreshold(config.tables_warn_threshold, config.tables_fail_threshold, "tables");
validateMaxIntThreshold(config.columns_per_table_warn_threshold, config.columns_per_table_fail_threshold, "columns_per_table");
validateMaxIntThreshold(config.secondary_indexes_per_table_warn_threshold, config.secondary_indexes_per_table_fail_threshold, "secondary_indexes_per_table");
validateMaxIntThreshold(config.materialized_views_per_table_warn_threshold, config.materialized_views_per_table_fail_threshold, "materialized_views_per_table");
config.table_properties_warned = validateTableProperties(config.table_properties_warned, "table_properties_warned");
config.table_properties_ignored = validateTableProperties(config.table_properties_ignored, "table_properties_ignored");
config.table_properties_disallowed = validateTableProperties(config.table_properties_disallowed, "table_properties_disallowed");
validateMaxIntThreshold(config.page_size_warn_threshold, config.page_size_fail_threshold, "page_size");
validateMaxIntThreshold(config.partition_keys_in_select_warn_threshold, config.partition_keys_in_select_fail_threshold, "partition_keys_in_select");
validateMaxIntThreshold(config.in_select_cartesian_product_warn_threshold, config.in_select_cartesian_product_fail_threshold, "in_select_cartesian_product");
config.read_consistency_levels_warned = validateConsistencyLevels(config.read_consistency_levels_warned, "read_consistency_levels_warned");
config.read_consistency_levels_disallowed = validateConsistencyLevels(config.read_consistency_levels_disallowed, "read_consistency_levels_disallowed");
config.write_consistency_levels_warned = validateConsistencyLevels(config.write_consistency_levels_warned, "write_consistency_levels_warned");
config.write_consistency_levels_disallowed = validateConsistencyLevels(config.write_consistency_levels_disallowed, "write_consistency_levels_disallowed");
validateSizeThreshold(config.collection_size_warn_threshold, config.collection_size_fail_threshold, false, "collection_size");
validateMaxIntThreshold(config.items_per_collection_warn_threshold, config.items_per_collection_fail_threshold, "items_per_collection");
validateMaxIntThreshold(config.fields_per_udt_warn_threshold, config.fields_per_udt_fail_threshold, "fields_per_udt");
validatePercentageThreshold(config.data_disk_usage_percentage_warn_threshold, config.data_disk_usage_percentage_fail_threshold, "data_disk_usage_percentage");
validateDataDiskUsageMaxDiskSize(config.data_disk_usage_max_disk_size);
validateMinRFThreshold(config.minimum_replication_factor_warn_threshold, config.minimum_replication_factor_fail_threshold, "minimum_replication_factor");
}
@Override
public int getKeyspacesWarnThreshold()
{
return config.keyspaces_warn_threshold;
}
@Override
public int getKeyspacesFailThreshold()
{
return config.keyspaces_fail_threshold;
}
public void setKeyspacesThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "keyspaces");
updatePropertyWithLogging("keyspaces_warn_threshold",
warn,
() -> config.keyspaces_warn_threshold,
x -> config.keyspaces_warn_threshold = x);
updatePropertyWithLogging("keyspaces_fail_threshold",
fail,
() -> config.keyspaces_fail_threshold,
x -> config.keyspaces_fail_threshold = x);
}
@Override
public int getTablesWarnThreshold()
{
return config.tables_warn_threshold;
}
@Override
public int getTablesFailThreshold()
{
return config.tables_fail_threshold;
}
public void setTablesThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "tables");
updatePropertyWithLogging("tables_warn_threshold",
warn,
() -> config.tables_warn_threshold,
x -> config.tables_warn_threshold = x);
updatePropertyWithLogging("tables_fail_threshold",
fail,
() -> config.tables_fail_threshold,
x -> config.tables_fail_threshold = x);
}
@Override
public int getColumnsPerTableWarnThreshold()
{
return config.columns_per_table_warn_threshold;
}
@Override
public int getColumnsPerTableFailThreshold()
{
return config.columns_per_table_fail_threshold;
}
public void setColumnsPerTableThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "columns_per_table");
updatePropertyWithLogging("columns_per_table_warn_threshold",
warn,
() -> config.columns_per_table_warn_threshold,
x -> config.columns_per_table_warn_threshold = x);
updatePropertyWithLogging("columns_per_table_fail_threshold",
fail,
() -> config.columns_per_table_fail_threshold,
x -> config.columns_per_table_fail_threshold = x);
}
@Override
public int getSecondaryIndexesPerTableWarnThreshold()
{
return config.secondary_indexes_per_table_warn_threshold;
}
@Override
public int getSecondaryIndexesPerTableFailThreshold()
{
return config.secondary_indexes_per_table_fail_threshold;
}
public void setSecondaryIndexesPerTableThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "secondary_indexes_per_table");
updatePropertyWithLogging("secondary_indexes_per_table_warn_threshold",
warn,
() -> config.secondary_indexes_per_table_warn_threshold,
x -> config.secondary_indexes_per_table_warn_threshold = x);
updatePropertyWithLogging("secondary_indexes_per_table_fail_threshold",
fail,
() -> config.secondary_indexes_per_table_fail_threshold,
x -> config.secondary_indexes_per_table_fail_threshold = x);
}
@Override
public int getMaterializedViewsPerTableWarnThreshold()
{
return config.materialized_views_per_table_warn_threshold;
}
@Override
public int getPartitionKeysInSelectWarnThreshold()
{
return config.partition_keys_in_select_warn_threshold;
}
@Override
public int getPartitionKeysInSelectFailThreshold()
{
return config.partition_keys_in_select_fail_threshold;
}
public void setPartitionKeysInSelectThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "partition_keys_in_select");
updatePropertyWithLogging("partition_keys_in_select_warn_threshold",
warn,
() -> config.partition_keys_in_select_warn_threshold,
x -> config.partition_keys_in_select_warn_threshold = x);
updatePropertyWithLogging("partition_keys_in_select_fail_threshold",
fail,
() -> config.partition_keys_in_select_fail_threshold,
x -> config.partition_keys_in_select_fail_threshold = x);
}
@Override
public int getMaterializedViewsPerTableFailThreshold()
{
return config.materialized_views_per_table_fail_threshold;
}
public void setMaterializedViewsPerTableThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "materialized_views_per_table");
updatePropertyWithLogging("materialized_views_per_table_warn_threshold",
warn,
() -> config.materialized_views_per_table_warn_threshold,
x -> config.materialized_views_per_table_warn_threshold = x);
updatePropertyWithLogging("materialized_views_per_table_fail_threshold",
fail,
() -> config.materialized_views_per_table_fail_threshold,
x -> config.materialized_views_per_table_fail_threshold = x);
}
@Override
public int getPageSizeWarnThreshold()
{
return config.page_size_warn_threshold;
}
@Override
public int getPageSizeFailThreshold()
{
return config.page_size_fail_threshold;
}
public void setPageSizeThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "page_size");
updatePropertyWithLogging("page_size_warn_threshold",
warn,
() -> config.page_size_warn_threshold,
x -> config.page_size_warn_threshold = x);
updatePropertyWithLogging("page_size_fail_threshold",
fail,
() -> config.page_size_fail_threshold,
x -> config.page_size_fail_threshold = x);
}
@Override
public Set<String> getTablePropertiesWarned()
{
return config.table_properties_warned;
}
public void setTablePropertiesWarned(Set<String> properties)
{
updatePropertyWithLogging("table_properties_warned",
validateTableProperties(properties, "table_properties_warned"),
() -> config.table_properties_warned,
x -> config.table_properties_warned = x);
}
@Override
public Set<String> getTablePropertiesIgnored()
{
return config.table_properties_ignored;
}
public void setTablePropertiesIgnored(Set<String> properties)
{
updatePropertyWithLogging("table_properties_ignored",
validateTableProperties(properties, "table_properties_ignored"),
() -> config.table_properties_ignored,
x -> config.table_properties_ignored = x);
}
@Override
public Set<String> getTablePropertiesDisallowed()
{
return config.table_properties_disallowed;
}
public void setTablePropertiesDisallowed(Set<String> properties)
{
updatePropertyWithLogging("table_properties_disallowed",
validateTableProperties(properties, "table_properties_disallowed"),
() -> config.table_properties_disallowed,
x -> config.table_properties_disallowed = x);
}
@Override
public boolean getUserTimestampsEnabled()
{
return config.user_timestamps_enabled;
}
public void setUserTimestampsEnabled(boolean enabled)
{
updatePropertyWithLogging("user_timestamps_enabled",
enabled,
() -> config.user_timestamps_enabled,
x -> config.user_timestamps_enabled = x);
}
@Override
public boolean getGroupByEnabled()
{
return config.group_by_enabled;
}
public void setGroupByEnabled(boolean enabled)
{
updatePropertyWithLogging("group_by_enabled",
enabled,
() -> config.group_by_enabled,
x -> config.group_by_enabled = x);
}
@Override
public boolean getDropTruncateTableEnabled()
{
return config.drop_truncate_table_enabled;
}
public void setDropTruncateTableEnabled(boolean enabled)
{
updatePropertyWithLogging("drop_truncate_table_enabled",
enabled,
() -> config.drop_truncate_table_enabled,
x -> config.drop_truncate_table_enabled = x);
}
@Override
public boolean getSecondaryIndexesEnabled()
{
return config.secondary_indexes_enabled;
}
public void setSecondaryIndexesEnabled(boolean enabled)
{
updatePropertyWithLogging("secondary_indexes_enabled",
enabled,
() -> config.secondary_indexes_enabled,
x -> config.secondary_indexes_enabled = x);
}
@Override
public boolean getUncompressedTablesEnabled()
{
return config.uncompressed_tables_enabled;
}
public void setUncompressedTablesEnabled(boolean enabled)
{
updatePropertyWithLogging("uncompressed_tables_enabled",
enabled,
() -> config.uncompressed_tables_enabled,
x -> config.uncompressed_tables_enabled = x);
}
@Override
public boolean getCompactTablesEnabled()
{
return config.compact_tables_enabled;
}
public void setCompactTablesEnabled(boolean enabled)
{
updatePropertyWithLogging("compact_tables_enabled",
enabled,
() -> config.compact_tables_enabled,
x -> config.compact_tables_enabled = x);
}
@Override
public boolean getReadBeforeWriteListOperationsEnabled()
{
return config.read_before_write_list_operations_enabled;
}
public void setReadBeforeWriteListOperationsEnabled(boolean enabled)
{
updatePropertyWithLogging("read_before_write_list_operations_enabled",
enabled,
() -> config.read_before_write_list_operations_enabled,
x -> config.read_before_write_list_operations_enabled = x);
}
@Override
public boolean getAllowFilteringEnabled()
{
return config.allow_filtering_enabled;
}
public void setAllowFilteringEnabled(boolean enabled)
{
updatePropertyWithLogging("allow_filtering_enabled",
enabled,
() -> config.allow_filtering_enabled,
x -> config.allow_filtering_enabled = x);
}
@Override
public int getInSelectCartesianProductWarnThreshold()
{
return config.in_select_cartesian_product_warn_threshold;
}
@Override
public int getInSelectCartesianProductFailThreshold()
{
return config.in_select_cartesian_product_fail_threshold;
}
public void setInSelectCartesianProductThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "in_select_cartesian_product");
updatePropertyWithLogging("in_select_cartesian_product_warn_threshold",
warn,
() -> config.in_select_cartesian_product_warn_threshold,
x -> config.in_select_cartesian_product_warn_threshold = x);
updatePropertyWithLogging("in_select_cartesian_product_fail_threshold",
fail,
() -> config.in_select_cartesian_product_fail_threshold,
x -> config.in_select_cartesian_product_fail_threshold = x);
}
public Set<ConsistencyLevel> getReadConsistencyLevelsWarned()
{
return config.read_consistency_levels_warned;
}
public void setReadConsistencyLevelsWarned(Set<ConsistencyLevel> consistencyLevels)
{
updatePropertyWithLogging("read_consistency_levels_warned",
validateConsistencyLevels(consistencyLevels, "read_consistency_levels_warned"),
() -> config.read_consistency_levels_warned,
x -> config.read_consistency_levels_warned = x);
}
@Override
public Set<ConsistencyLevel> getReadConsistencyLevelsDisallowed()
{
return config.read_consistency_levels_disallowed;
}
public void setReadConsistencyLevelsDisallowed(Set<ConsistencyLevel> consistencyLevels)
{
updatePropertyWithLogging("read_consistency_levels_disallowed",
validateConsistencyLevels(consistencyLevels, "read_consistency_levels_disallowed"),
() -> config.read_consistency_levels_disallowed,
x -> config.read_consistency_levels_disallowed = x);
}
@Override
public Set<ConsistencyLevel> getWriteConsistencyLevelsWarned()
{
return config.write_consistency_levels_warned;
}
public void setWriteConsistencyLevelsWarned(Set<ConsistencyLevel> consistencyLevels)
{
updatePropertyWithLogging("write_consistency_levels_warned",
validateConsistencyLevels(consistencyLevels, "write_consistency_levels_warned"),
() -> config.write_consistency_levels_warned,
x -> config.write_consistency_levels_warned = x);
}
@Override
public Set<ConsistencyLevel> getWriteConsistencyLevelsDisallowed()
{
return config.write_consistency_levels_disallowed;
}
public void setWriteConsistencyLevelsDisallowed(Set<ConsistencyLevel> consistencyLevels)
{
updatePropertyWithLogging("write_consistency_levels_disallowed",
validateConsistencyLevels(consistencyLevels, "write_consistency_levels_disallowed"),
() -> config.write_consistency_levels_disallowed,
x -> config.write_consistency_levels_disallowed = x);
}
@Override
@Nullable
public DataStorageSpec.LongBytesBound getCollectionSizeWarnThreshold()
{
return config.collection_size_warn_threshold;
}
@Override
@Nullable
public DataStorageSpec.LongBytesBound getCollectionSizeFailThreshold()
{
return config.collection_size_fail_threshold;
}
public void setCollectionSizeThreshold(@Nullable DataStorageSpec.LongBytesBound warn, @Nullable DataStorageSpec.LongBytesBound fail)
{
validateSizeThreshold(warn, fail, false, "collection_size");
updatePropertyWithLogging("collection_size_warn_threshold",
warn,
() -> config.collection_size_warn_threshold,
x -> config.collection_size_warn_threshold = x);
updatePropertyWithLogging("collection_size_fail_threshold",
fail,
() -> config.collection_size_fail_threshold,
x -> config.collection_size_fail_threshold = x);
}
@Override
public int getItemsPerCollectionWarnThreshold()
{
return config.items_per_collection_warn_threshold;
}
@Override
public int getItemsPerCollectionFailThreshold()
{
return config.items_per_collection_fail_threshold;
}
public void setItemsPerCollectionThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "items_per_collection");
updatePropertyWithLogging("items_per_collection_warn_threshold",
warn,
() -> config.items_per_collection_warn_threshold,
x -> config.items_per_collection_warn_threshold = x);
updatePropertyWithLogging("items_per_collection_fail_threshold",
fail,
() -> config.items_per_collection_fail_threshold,
x -> config.items_per_collection_fail_threshold = x);
}
@Override
public int getFieldsPerUDTWarnThreshold()
{
return config.fields_per_udt_warn_threshold;
}
@Override
public int getFieldsPerUDTFailThreshold()
{
return config.fields_per_udt_fail_threshold;
}
public void setFieldsPerUDTThreshold(int warn, int fail)
{
validateMaxIntThreshold(warn, fail, "fields_per_udt");
updatePropertyWithLogging("fields_per_udt_warn_threshold",
warn,
() -> config.fields_per_udt_warn_threshold,
x -> config.fields_per_udt_warn_threshold = x);
updatePropertyWithLogging("fields_per_udt_fail_threshold",
fail,
() -> config.fields_per_udt_fail_threshold,
x -> config.fields_per_udt_fail_threshold = x);
}
public int getDataDiskUsagePercentageWarnThreshold()
{
return config.data_disk_usage_percentage_warn_threshold;
}
@Override
public int getDataDiskUsagePercentageFailThreshold()
{
return config.data_disk_usage_percentage_fail_threshold;
}
public void setDataDiskUsagePercentageThreshold(int warn, int fail)
{
validatePercentageThreshold(warn, fail, "data_disk_usage_percentage");
updatePropertyWithLogging("data_disk_usage_percentage_warn_threshold",
warn,
() -> config.data_disk_usage_percentage_warn_threshold,
x -> config.data_disk_usage_percentage_warn_threshold = x);
updatePropertyWithLogging("data_disk_usage_percentage_fail_threshold",
fail,
() -> config.data_disk_usage_percentage_fail_threshold,
x -> config.data_disk_usage_percentage_fail_threshold = x);
}
@Override
public DataStorageSpec.LongBytesBound getDataDiskUsageMaxDiskSize()
{
return config.data_disk_usage_max_disk_size;
}
public void setDataDiskUsageMaxDiskSize(@Nullable DataStorageSpec.LongBytesBound diskSize)
{
validateDataDiskUsageMaxDiskSize(diskSize);
updatePropertyWithLogging("data_disk_usage_max_disk_size",
diskSize,
() -> config.data_disk_usage_max_disk_size,
x -> config.data_disk_usage_max_disk_size = x);
}
@Override
public int getMinimumReplicationFactorWarnThreshold()
{
return config.minimum_replication_factor_warn_threshold;
}
@Override
public int getMinimumReplicationFactorFailThreshold()
{
return config.minimum_replication_factor_fail_threshold;
}
public void setMinimumReplicationFactorThreshold(int warn, int fail)
{
validateMinRFThreshold(warn, fail, "minimum_replication_factor");
updatePropertyWithLogging("minimum_replication_factor_warn_threshold",
warn,
() -> config.minimum_replication_factor_warn_threshold,
x -> config.minimum_replication_factor_warn_threshold = x);
updatePropertyWithLogging("minimum_replication_factor_fail_threshold",
fail,
() -> config.minimum_replication_factor_fail_threshold,
x -> config.minimum_replication_factor_fail_threshold = x);
}
private static <T> void updatePropertyWithLogging(String propertyName, T newValue, Supplier<T> getter, Consumer<T> setter)
{
T oldValue = getter.get();
if (newValue == null || !newValue.equals(oldValue))
{
setter.accept(newValue);
logger.info("Updated {} from {} to {}", propertyName, oldValue, newValue);
}
}
private static void validatePositiveNumeric(long value, long maxValue, String name)
{
if (value == -1)
return;
if (value > maxValue)
throw new IllegalArgumentException(format("Invalid value %d for %s: maximum allowed value is %d",
value, name, maxValue));
if (value == 0)
throw new IllegalArgumentException(format("Invalid value for %s: 0 is not allowed; " +
"if attempting to disable use -1", name));
// We allow -1 as a general "disabling" flag. But reject anything lower to avoid mistakes.
if (value <= 0)
throw new IllegalArgumentException(format("Invalid value %d for %s: negative values are not allowed, " +
"outside of -1 which disables the guardrail", value, name));
}
private static void validatePercentage(long value, String name)
{
validatePositiveNumeric(value, 100, name);
}
private static void validatePercentageThreshold(int warn, int fail, String name)
{
validatePercentage(warn, name + "_warn_threshold");
validatePercentage(fail, name + "_fail_threshold");
validateWarnLowerThanFail(warn, fail, name);
}
private static void validateMaxIntThreshold(int warn, int fail, String name)
{
validatePositiveNumeric(warn, Integer.MAX_VALUE, name + "_warn_threshold");
validatePositiveNumeric(fail, Integer.MAX_VALUE, name + "_fail_threshold");
validateWarnLowerThanFail(warn, fail, name);
}
private static void validateMinIntThreshold(int warn, int fail, String name)
{
validatePositiveNumeric(warn, Integer.MAX_VALUE, name + "_warn_threshold");
validatePositiveNumeric(fail, Integer.MAX_VALUE, name + "_fail_threshold");
validateWarnGreaterThanFail(warn, fail, name);
}
private static void validateMinRFThreshold(int warn, int fail, String name)
{
validateMinIntThreshold(warn, fail, name);
validateMinRFVersusDefaultRF(fail, name);
}
private static void validateWarnLowerThanFail(long warn, long fail, String name)
{
if (warn == -1 || fail == -1)
return;
if (fail < warn)
throw new IllegalArgumentException(format("The warn threshold %d for %s_warn_threshold should be lower " +
"than the fail threshold %d", warn, name, fail));
}
private static void validateWarnGreaterThanFail(long warn, long fail, String name)
{
if (warn == -1 || fail == -1)
return;
if (fail > warn)
throw new IllegalArgumentException(format("The warn threshold %d for %s_warn_threshold should be greater " +
"than the fail threshold %d", warn, name, fail));
}
private static void validateMinRFVersusDefaultRF(int fail, String name) throws IllegalArgumentException
{
if (fail > DatabaseDescriptor.getDefaultKeyspaceRF())
{
throw new IllegalArgumentException(String.format("%s_fail_threshold to be set (%d) cannot be greater than default_keyspace_rf (%d)",
name, fail, DatabaseDescriptor.getDefaultKeyspaceRF()));
}
}
private static void validateSize(DataStorageSpec.LongBytesBound size, boolean allowZero, String name)
{
if (size == null)
return;
if (!allowZero && size.toBytes() == 0)
throw new IllegalArgumentException(format("Invalid value for %s: 0 is not allowed; " +
"if attempting to disable use an empty value",
name));
}
private static void validateSizeThreshold(DataStorageSpec.LongBytesBound warn, DataStorageSpec.LongBytesBound fail, boolean allowZero, String name)
{
validateSize(warn, allowZero, name + "_warn_threshold");
validateSize(fail, allowZero, name + "_fail_threshold");
validateWarnLowerThanFail(warn, fail, name);
}
private static void validateWarnLowerThanFail(DataStorageSpec.LongBytesBound warn, DataStorageSpec.LongBytesBound fail, String name)
{
if (warn == null || fail == null)
return;
if (fail.toBytes() < warn.toBytes())
throw new IllegalArgumentException(format("The warn threshold %s for %s_warn_threshold should be lower " +
"than the fail threshold %s", warn, name, fail));
}
private static Set<String> validateTableProperties(Set<String> properties, String name)
{
if (properties == null)
throw new IllegalArgumentException(format("Invalid value for %s: null is not allowed", name));
Set<String> lowerCaseProperties = properties.stream().map(String::toLowerCase).collect(toSet());
Set<String> diff = Sets.difference(lowerCaseProperties, TableAttributes.allKeywords());
if (!diff.isEmpty())
throw new IllegalArgumentException(format("Invalid value for %s: '%s' do not parse as valid table properties",
name, diff));
return lowerCaseProperties;
}
private static Set<ConsistencyLevel> validateConsistencyLevels(Set<ConsistencyLevel> consistencyLevels, String name)
{
if (consistencyLevels == null)
throw new IllegalArgumentException(format("Invalid value for %s: null is not allowed", name));
return consistencyLevels.isEmpty() ? Collections.emptySet() : Sets.immutableEnumSet(consistencyLevels);
}
private static void validateDataDiskUsageMaxDiskSize(DataStorageSpec.LongBytesBound maxDiskSize)
{
if (maxDiskSize == null)
return;
validateSize(maxDiskSize, false, "data_disk_usage_max_disk_size");
long diskSize = DiskUsageMonitor.totalDiskSpace();
if (diskSize < maxDiskSize.toBytes())
throw new IllegalArgumentException(format("Invalid value for data_disk_usage_max_disk_size: " +
"%s specified, but only %s are actually available on disk",
maxDiskSize, FileUtils.stringifyFileSize(diskSize)));
}
}