From 46b36f23cd865ee905742ff1d3da05fc8a467758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ata=20=C4=B0lhan=20K=C3=B6kt=C3=BCrk?= Date: Sun, 29 Sep 2024 12:31:34 +0800 Subject: [PATCH] Explicitly localize strings to Locale.US for internal implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is inconsistent usage of toLowerCase/toUpperCase methods in the codebase. Somewhere we already use Locale.US, somewhere not. That might cause various issues in runtime as shown in CASSANDRA-19953 ticket when an environment Cassandra runs in has different locale from expected. In this patch, all such method calls explicitly set their locale to Locale.US. This patch also contains a checkstyle rule which fails the compilation if toLowerCase or toUpperCase is used. We prefer calls to methods in LocalizeString class which use US locale. patch by Ata İlhan Köktürk; reviewed by Stefan Miklosovic, Brandon Williams for CASSANDRA-19953 Co-authored-by: Maxwell Guo Co-authored-by: Stefan Miklosovic --- .build/checkstyle.xml | 16 ++++- CHANGES.txt | 1 + src/antlr/Cql.g | 1 + src/antlr/Parser.g | 6 +- .../cassandra/audit/AuditLogManager.java | 4 +- .../cassandra/audit/AuditLogOptions.java | 12 ++-- .../apache/cassandra/concurrent/Stage.java | 3 +- .../config/CassandraRelevantProperties.java | 12 ++-- .../apache/cassandra/config/DataRateSpec.java | 7 ++- .../cassandra/config/DataStorageSpec.java | 7 ++- .../cassandra/config/DatabaseDescriptor.java | 6 +- .../apache/cassandra/config/DurationSpec.java | 10 ++-- .../cassandra/config/EncryptionOptions.java | 12 ++-- .../org/apache/cassandra/cql3/CQL3Type.java | 3 +- .../cassandra/cql3/ColumnIdentifier.java | 7 ++- .../org/apache/cassandra/cql3/Duration.java | 3 +- .../cassandra/cql3/FieldIdentifier.java | 5 +- .../cassandra/cql3/PasswordObfuscator.java | 6 +- .../apache/cassandra/cql3/QualifiedName.java | 5 +- .../cassandra/cql3/ReservedKeywords.java | 4 +- .../org/apache/cassandra/cql3/RoleName.java | 4 +- .../apache/cassandra/cql3/SchemaElement.java | 5 +- .../cassandra/cql3/functions/CastFcts.java | 3 +- .../cql3/functions/FunctionResolver.java | 3 +- .../functions/masking/MaskingFunction.java | 4 +- .../cql3/functions/types/DataType.java | 4 +- .../cql3/functions/types/Duration.java | 3 +- .../cql3/functions/types/Metadata.java | 4 +- .../cassandra/cql3/selection/Selectable.java | 3 +- .../cassandra/cql3/selection/Selection.java | 4 +- .../cql3/statements/PropertyDefinitions.java | 3 +- .../apache/cassandra/db/ConsistencyLevel.java | 6 +- .../org/apache/cassandra/db/Directories.java | 6 +- .../db/compaction/OperationType.java | 4 +- .../db/compaction/unified/Controller.java | 9 +-- .../cassandra/db/lifecycle/LogRecord.java | 4 +- .../cassandra/db/marshal/CollectionType.java | 7 ++- .../cassandra/db/marshal/EmptyType.java | 3 +- .../apache/cassandra/db/marshal/UserType.java | 3 +- .../cassandra/db/virtual/ClientsTable.java | 4 +- .../CollectionVirtualTableAdapter.java | 3 +- .../cassandra/db/virtual/GossipInfoTable.java | 9 +-- .../db/virtual/LocalRepairTables.java | 6 +- .../db/virtual/SSTableTasksTable.java | 6 +- .../db/virtual/StreamingVirtualTable.java | 8 ++- .../db/virtual/VirtualSchemaKeyspace.java | 5 +- .../sai/analyzer/filter/BasicFilters.java | 4 +- .../index/sai/disk/v1/IndexWriterConfig.java | 5 +- .../index/sai/disk/v1/vector/OptimizeFor.java | 3 +- .../analyzer/filter/BasicResultFilters.java | 7 ++- .../index/sasi/disk/OnDiskIndexBuilder.java | 4 +- .../metrics/CassandraMetricsRegistry.java | 6 +- .../cassandra/schema/CQLTypeParser.java | 8 ++- .../cassandra/schema/CachingParams.java | 3 +- .../cassandra/schema/CompactionParams.java | 8 ++- .../cassandra/schema/IndexMetadata.java | 5 +- .../cassandra/schema/KeyspaceParams.java | 4 +- .../cassandra/schema/SchemaConstants.java | 8 ++- .../cassandra/schema/SchemaKeyspace.java | 16 ++--- .../apache/cassandra/schema/TableParams.java | 3 +- .../cassandra/security/JKSKeyProvider.java | 4 +- .../apache/cassandra/security/SSLFactory.java | 3 +- .../serializers/CollectionSerializer.java | 5 +- .../cassandra/service/StartupChecks.java | 3 +- .../cassandra/service/StorageProxy.java | 3 +- .../service/paxos/ContentionStrategy.java | 3 +- .../reads/HybridSpeculativeRetryPolicy.java | 4 +- .../reads/repair/ReadRepairStrategy.java | 4 +- .../streaming/StreamResultFuture.java | 3 +- .../cassandra/streaming/StreamingState.java | 5 +- .../apache/cassandra/tcm/MetadataKeys.java | 4 +- .../apache/cassandra/tools/RepairRunner.java | 5 +- .../cassandra/tools/StandaloneScrubber.java | 6 +- .../cassandra/tools/nodetool/ProfileLoad.java | 3 +- .../apache/cassandra/transport/CBUtil.java | 5 +- .../apache/cassandra/transport/Client.java | 13 ++-- .../transport/messages/StartupMessage.java | 7 ++- .../apache/cassandra/utils/FBUtilities.java | 7 ++- .../apache/cassandra/utils/GuidGenerator.java | 3 +- .../org/apache/cassandra/utils/JsonUtils.java | 4 +- .../cassandra/utils/LocalizeString.java | 60 +++++++++++++++++++ .../apache/cassandra/utils/NativeLibrary.java | 5 +- .../utils/NativeSSTableLoaderClient.java | 8 ++- .../apache/cassandra/utils/binlog/BinLog.java | 3 +- .../apache/cassandra/distributed/Cluster.java | 4 +- .../distributed/test/FailingRepairTest.java | 4 +- .../test/ReadDigestConsistencyTest.java | 4 +- .../test/RepairCoordinatorBase.java | 3 +- .../RepairCoordinatorFailingMessageTest.java | 3 +- .../test/SSTableIdGenerationTest.java | 5 +- .../compaction/CompactionAllocationTest.java | 10 ++-- .../apache/cassandra/simulator/Action.java | 2 +- .../cassandra/simulator/SimulationRunner.java | 5 +- .../org/apache/cassandra/SchemaLoader.java | 3 +- .../auth/CassandraNetworkAuthorizerTest.java | 3 +- .../cassandra/config/DataStorageSpecTest.java | 3 +- .../config/DatabaseDescriptorRefTest.java | 1 + .../org/apache/cassandra/cql3/CQLTester.java | 8 +-- .../cassandra/cql3/KeywordTestBase.java | 4 +- .../cql3/functions/NativeFunctionsTest.java | 8 ++- .../masking/PartialMaskingFunctionTest.java | 3 +- .../entities/SecondaryIndexTest.java | 12 ++-- .../db/compaction/unified/ControllerTest.java | 3 +- .../db/guardrails/GuardrailPasswordTest.java | 3 +- .../cassandra/db/tries/TrieToDotTest.java | 4 +- .../cassandra/db/tries/TrieToMermaidTest.java | 4 +- .../db/virtual/LocalRepairTablesTest.java | 4 +- .../db/virtual/SSTableTasksTableTest.java | 3 +- .../db/virtual/StreamingVirtualTableTest.java | 5 +- .../sai/analyzer/filter/BasicFiltersTest.java | 3 +- .../sasi/analyzer/DelimiterAnalyzerTest.java | 5 +- .../analyzer/NonTokenizingAnalyzerTest.java | 6 +- .../reads/repair/AbstractReadRepairTest.java | 3 +- .../cassandra/tools/TopPartitionsTest.java | 4 +- .../apache/cassandra/stress/StressAction.java | 3 +- .../apache/cassandra/stress/StressGraph.java | 4 +- .../cassandra/stress/StressProfile.java | 17 +++--- .../cassandra/stress/settings/CliOption.java | 6 +- .../cassandra/stress/settings/Command.java | 12 ++-- .../stress/settings/OptionDistribution.java | 8 ++- .../settings/OptionEnumProbabilities.java | 3 +- .../stress/settings/SettingsCommand.java | 15 +++-- .../settings/SettingsCommandPreDefined.java | 6 +- .../stress/settings/SettingsLog.java | 4 +- .../stress/settings/SettingsMisc.java | 8 ++- .../stress/settings/SettingsMode.java | 3 +- .../stress/settings/SettingsPopulation.java | 4 +- .../stress/settings/StressSettings.java | 4 +- 128 files changed, 493 insertions(+), 243 deletions(-) create mode 100644 src/java/org/apache/cassandra/utils/LocalizeString.java diff --git a/.build/checkstyle.xml b/.build/checkstyle.xml index 8b81f21281..bc9b5c02de 100644 --- a/.build/checkstyle.xml +++ b/.build/checkstyle.xml @@ -62,7 +62,13 @@ - + + + + + + + @@ -151,6 +157,14 @@ + + + + + + + + diff --git a/CHANGES.txt b/CHANGES.txt index 7e5d6fede4..f4e9d0f5fa 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * Explicitly localize strings to Locale.US for internal implementation (CASSANDRA-19953) * Add -H option for human-friendly output in nodetool compactionhistory (CASSANDRA-20015) * Fix type check for referenced duration type for nested types (CASSANDRA-19890) * In simulation tests, correctly set the tokens of replacement nodes (CASSANDRA-19997) diff --git a/src/antlr/Cql.g b/src/antlr/Cql.g index b25f3944d6..5cf8c88a31 100644 --- a/src/antlr/Cql.g +++ b/src/antlr/Cql.g @@ -50,6 +50,7 @@ import Parser,Lexer; import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.schema.ColumnMetadata; import org.apache.cassandra.utils.Pair; + import org.apache.cassandra.utils.LocalizeString; } @members { diff --git a/src/antlr/Parser.g b/src/antlr/Parser.g index 099feaa1db..15c2a0140b 100644 --- a/src/antlr/Parser.g +++ b/src/antlr/Parser.g @@ -722,7 +722,7 @@ createFunctionStatement returns [CreateFunctionStatement.Raw stmt] K_LANGUAGE language = IDENT K_AS body = STRING_LITERAL { $stmt = new CreateFunctionStatement.Raw( - fn, argNames, argTypes, returnType, calledOnNullInput, $language.text.toLowerCase(), $body.text, orReplace, ifNotExists); + fn, argNames, argTypes, returnType, calledOnNullInput, LocalizeString.toLowerCaseLocalized($language.text), $body.text, orReplace, ifNotExists); } ; @@ -1127,7 +1127,7 @@ listPermissionsStatement returns [ListPermissionsStatement stmt] permission returns [Permission perm] : p=(K_CREATE | K_ALTER | K_DROP | K_SELECT | K_MODIFY | K_AUTHORIZE | K_DESCRIBE | K_EXECUTE | K_UNMASK | K_SELECT_MASKED) - { $perm = Permission.valueOf($p.text.toUpperCase()); } + { $perm = Permission.valueOf(LocalizeString.toUpperCaseLocalized($p.text)); } ; permissionOrAll returns [Set perms] @@ -1642,7 +1642,7 @@ functionName returns [FunctionName s] ; allowedFunctionName returns [String s] - : f=IDENT { $s = $f.text.toLowerCase(); } + : f=IDENT { $s = LocalizeString.toLowerCaseLocalized($f.text); } | f=QUOTED_NAME { $s = $f.text; } | u=unreserved_function_keyword { $s = u; } | K_TOKEN { $s = "token"; } diff --git a/src/java/org/apache/cassandra/audit/AuditLogManager.java b/src/java/org/apache/cassandra/audit/AuditLogManager.java index 85f754f019..0f49a54060 100644 --- a/src/java/org/apache/cassandra/audit/AuditLogManager.java +++ b/src/java/org/apache/cassandra/audit/AuditLogManager.java @@ -51,6 +51,8 @@ import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.MBeanWrapper; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * Central location for managing the logging of client/user-initated actions (like queries, log in commands, and so on). * @@ -387,7 +389,7 @@ public class AuditLogManager implements QueryEvents.Listener, AuthEvents.Listene { for (String query : queries) { - if (query.toLowerCase().contains(PasswordObfuscator.PASSWORD_TOKEN)) + if (toLowerCaseLocalized(query).contains(PasswordObfuscator.PASSWORD_TOKEN)) return "Syntax Exception. Obscured for security reasons."; } } diff --git a/src/java/org/apache/cassandra/audit/AuditLogOptions.java b/src/java/org/apache/cassandra/audit/AuditLogOptions.java index e9e31c9040..196bd9d0ef 100644 --- a/src/java/org/apache/cassandra/audit/AuditLogOptions.java +++ b/src/java/org/apache/cassandra/audit/AuditLogOptions.java @@ -34,6 +34,8 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.util.File; import org.apache.cassandra.utils.binlog.BinLogOptions; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class AuditLogOptions extends BinLogOptions { public volatile boolean enabled = false; @@ -143,13 +145,13 @@ public class AuditLogOptions extends BinLogOptions public Builder withIncludedCategories(final String includedCategories) { - sanitise(includedCategories).map(v -> this.includedCategories = v.toUpperCase()); + sanitise(includedCategories).map(v -> this.includedCategories = toUpperCaseLocalized(v)); return this; } public Builder withExcludedCategories(final String excludedCategories) { - sanitise(excludedCategories).map(v -> this.excludedCategories = v.toUpperCase()); + sanitise(excludedCategories).map(v -> this.excludedCategories = toUpperCaseLocalized(v)); return this; } @@ -173,7 +175,7 @@ public class AuditLogOptions extends BinLogOptions public Builder withRollCycle(final String rollCycle) { - sanitise(rollCycle).map(v -> this.rollCycle = v.toUpperCase()); + sanitise(rollCycle).map(v -> this.rollCycle = toUpperCaseLocalized(v)); return this; } @@ -230,8 +232,8 @@ public class AuditLogOptions extends BinLogOptions opts.logger = this.logger; sanitise(this.includedKeyspaces).map(v -> opts.included_keyspaces = v); sanitise(this.excludedKeyspaces).map(v -> opts.excluded_keyspaces = v); - sanitise(this.includedCategories).map(v -> opts.included_categories = v.toUpperCase()); - sanitise(this.excludedCategories).map(v -> opts.excluded_categories = v.toUpperCase()); + sanitise(this.includedCategories).map(v -> opts.included_categories = toUpperCaseLocalized(v)); + sanitise(this.excludedCategories).map(v -> opts.excluded_categories = toUpperCaseLocalized(v)); sanitise(this.includedUsers).map(v -> opts.included_users = v); sanitise(this.excludedUsers).map(v -> opts.excluded_users = v); opts.roll_cycle = this.rollCycle; diff --git a/src/java/org/apache/cassandra/concurrent/Stage.java b/src/java/org/apache/cassandra/concurrent/Stage.java index 4def177422..23f80b5a57 100644 --- a/src/java/org/apache/cassandra/concurrent/Stage.java +++ b/src/java/org/apache/cassandra/concurrent/Stage.java @@ -39,6 +39,7 @@ import org.apache.cassandra.utils.concurrent.Future; import static java.util.stream.Collectors.toMap; import static org.apache.cassandra.concurrent.ExecutorFactory.Global.executorFactory; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public enum Stage { @@ -79,7 +80,7 @@ public enum Stage private static String normalizeName(String stageName) { // Handle discrepancy between JMX names and actual pool names - String upperStageName = stageName.toUpperCase(); + String upperStageName = toUpperCaseLocalized(stageName); if (upperStageName.endsWith("STAGE")) { upperStageName = upperStageName.substring(0, stageName.length() - 5); diff --git a/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java b/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java index b98d1b2d9d..fcf9f7d0e6 100644 --- a/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java +++ b/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java @@ -32,6 +32,8 @@ import org.apache.cassandra.service.FileSystemOwnershipCheck; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.StorageCompatibilityMode; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + // checkstyle: suppress below 'blockSystemPropertyUsage' /** A class that extracts system properties for the cassandra node it runs within. */ @@ -918,7 +920,7 @@ public enum CassandraRelevantProperties } /** - * Gets the value of a system property as a enum, calling {@link String#toUpperCase()} first. + * Gets the value of a system property as an enum, calling {@link org.apache.cassandra.utils.LocalizeString#toUpperCaseLocalized(String)} first. * * @param defaultValue to return when not defined * @param type @@ -930,7 +932,7 @@ public enum CassandraRelevantProperties } /** - * Gets the value of a system property as a enum, optionally calling {@link String#toUpperCase()} first. + * Gets the value of a system property as an enum, optionally calling {@link org.apache.cassandra.utils.LocalizeString#toUpperCaseLocalized(String)} first. * * @param toUppercase before converting to enum * @param defaultValue to return when not defined @@ -942,11 +944,11 @@ public enum CassandraRelevantProperties String value = System.getProperty(key); if (value == null) return defaultValue; - return Enum.valueOf(defaultValue.getDeclaringClass(), toUppercase ? value.toUpperCase() : value); + return Enum.valueOf(defaultValue.getDeclaringClass(), toUppercase ? toUpperCaseLocalized(value) : value); } /** - * Gets the value of a system property as an enum, optionally calling {@link String#toUpperCase()} first. + * Gets the value of a system property as an enum, optionally calling {@link org.apache.cassandra.utils.LocalizeString#toLowerCaseLocalized(String)} first. * If the value is missing, the default value for this property is used * * @param toUppercase before converting to enum @@ -957,7 +959,7 @@ public enum CassandraRelevantProperties public > T getEnum(boolean toUppercase, Class enumClass) { String value = System.getProperty(key, defaultVal); - return Enum.valueOf(enumClass, toUppercase ? value.toUpperCase() : value); + return Enum.valueOf(enumClass, toUppercase ? toUpperCaseLocalized(value) : value); } /** diff --git a/src/java/org/apache/cassandra/config/DataRateSpec.java b/src/java/org/apache/cassandra/config/DataRateSpec.java index d496cfa671..a89cd8413e 100644 --- a/src/java/org/apache/cassandra/config/DataRateSpec.java +++ b/src/java/org/apache/cassandra/config/DataRateSpec.java @@ -27,6 +27,7 @@ import com.google.common.math.DoubleMath; import com.google.common.primitives.Ints; import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.BYTES_PER_SECOND; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * Represents a data rate type used for cassandra configuration. It supports the opportunity for the users to be able to @@ -76,7 +77,7 @@ public abstract class DataRateSpec // negatives are not allowed by the regex pattern if (minUnit.convert(quantity, unit) >= max) throw new IllegalArgumentException("Invalid data rate: " + value + ". It shouldn't be more than " + - (max - 1) + " in " + minUnit.name().toLowerCase()); + (max - 1) + " in " + toLowerCaseLocalized(minUnit.name())); } private static void validateQuantity(double quantity, DataRateUnit unit, DataRateUnit minUnit, long max) @@ -86,8 +87,8 @@ public abstract class DataRateSpec if (minUnit.convert(quantity, unit) >= max) throw new IllegalArgumentException(String.format("Invalid data rate: %s %s. It shouldn't be more than %d in %s", - quantity, unit.name().toLowerCase(), - max - 1, minUnit.name().toLowerCase())); + quantity, toLowerCaseLocalized(unit.name()), + max - 1, toLowerCaseLocalized(minUnit.name()))); } // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is diff --git a/src/java/org/apache/cassandra/config/DataStorageSpec.java b/src/java/org/apache/cassandra/config/DataStorageSpec.java index b5d4374088..53d71717ef 100644 --- a/src/java/org/apache/cassandra/config/DataStorageSpec.java +++ b/src/java/org/apache/cassandra/config/DataStorageSpec.java @@ -28,6 +28,7 @@ import com.google.common.primitives.Ints; import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.BYTES; import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES; import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * Represents an amount of data storage. Wrapper class for Cassandra configuration parameters, providing to the @@ -99,7 +100,7 @@ public abstract class DataStorageSpec if (minUnit.convert(quantity, sourceUnit) >= max) throw new IllegalArgumentException("Invalid data storage: " + value + ". It shouldn't be more than " + - (max - 1) + " in " + minUnit.name().toLowerCase()); + (max - 1) + " in " + toLowerCaseLocalized(minUnit.name())); } private static void validateQuantity(long quantity, DataStorageUnit sourceUnit, DataStorageUnit minUnit, long max) @@ -109,8 +110,8 @@ public abstract class DataStorageSpec if (minUnit.convert(quantity, sourceUnit) >= max) throw new IllegalArgumentException(String.format("Invalid data storage: %d %s. It shouldn't be more than %d in %s", - quantity, sourceUnit.name().toLowerCase(), - max - 1, minUnit.name().toLowerCase())); + quantity, toLowerCaseLocalized(sourceUnit.name()), + max - 1, toLowerCaseLocalized(minUnit.name()))); } // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 7699a809a4..784a079320 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -62,7 +62,7 @@ import com.google.common.collect.Sets; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.util.concurrent.RateLimiter; -import org.apache.cassandra.utils.Pair; + import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -116,6 +116,7 @@ import org.apache.cassandra.service.StorageService; import org.apache.cassandra.service.paxos.Paxos; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.MBeanWrapper; +import org.apache.cassandra.utils.Pair; import org.apache.cassandra.utils.StorageCompatibilityMode; import static org.apache.cassandra.config.CassandraRelevantProperties.ALLOCATE_TOKENS_FOR_KEYSPACE; @@ -156,6 +157,7 @@ import static org.apache.cassandra.db.ConsistencyLevel.QUORUM; import static org.apache.cassandra.io.util.FileUtils.ONE_GIB; import static org.apache.cassandra.io.util.FileUtils.ONE_MIB; import static org.apache.cassandra.utils.Clock.Global.logInitializationOutcome; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public class DatabaseDescriptor { @@ -1785,7 +1787,7 @@ public class DatabaseDescriptor if (cidrAuthorizerMode == null || cidrAuthorizerMode.isEmpty()) return defaultCidrAuthorizerMode; - return ICIDRAuthorizer.CIDRAuthorizerMode.valueOf(cidrAuthorizerMode.toUpperCase()); + return ICIDRAuthorizer.CIDRAuthorizerMode.valueOf(toUpperCaseLocalized(cidrAuthorizerMode)); } public static int getCidrGroupsCacheRefreshInterval() diff --git a/src/java/org/apache/cassandra/config/DurationSpec.java b/src/java/org/apache/cassandra/config/DurationSpec.java index 2522d86124..3a9a03ab1f 100644 --- a/src/java/org/apache/cassandra/config/DurationSpec.java +++ b/src/java/org/apache/cassandra/config/DurationSpec.java @@ -34,6 +34,8 @@ import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * 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 @@ -108,7 +110,7 @@ public abstract class DurationSpec if (minUnit.convert(quantity, sourceUnit) >= max) throw new IllegalArgumentException("Invalid duration: " + value + ". It shouldn't be more than " + - (max - 1) + " in " + minUnit.name().toLowerCase()); + (max - 1) + " in " + toLowerCaseLocalized(minUnit.name())); } private static void validateQuantity(long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max) @@ -118,8 +120,8 @@ public abstract class DurationSpec if (minUnit.convert(quantity, sourceUnit) >= max) throw new IllegalArgumentException(String.format("Invalid duration: %d %s. It shouldn't be more than %d in %s", - quantity, sourceUnit.name().toLowerCase(), - max - 1, minUnit.name().toLowerCase())); + quantity, toLowerCaseLocalized(sourceUnit.name()), + max - 1, toLowerCaseLocalized(minUnit.name()))); } // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is @@ -141,7 +143,7 @@ public abstract class DurationSpec */ static TimeUnit fromSymbol(String symbol) { - switch (symbol.toLowerCase()) + switch (toLowerCaseLocalized(symbol)) { case "d": return DAYS; case "h": return HOURS; diff --git a/src/java/org/apache/cassandra/config/EncryptionOptions.java b/src/java/org/apache/cassandra/config/EncryptionOptions.java index 6471eea9e3..fdc5c0efc6 100644 --- a/src/java/org/apache/cassandra/config/EncryptionOptions.java +++ b/src/java/org/apache/cassandra/config/EncryptionOptions.java @@ -38,6 +38,8 @@ import org.apache.cassandra.security.DisableSslContextFactory; import org.apache.cassandra.security.ISslContextFactory; import org.apache.cassandra.utils.FBUtilities; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * This holds various options used for enabling SSL/TLS encryption. * Examples of such options are: supported cipher-suites, ssl protocol with version, accepted protocols, end-point @@ -78,7 +80,7 @@ public class EncryptionOptions for (ClientAuth clientAuth : ClientAuth.values()) { VALUES.put(clientAuth.value, clientAuth); - VALUES.put(clientAuth.name().toLowerCase(), clientAuth); + VALUES.put(toLowerCaseLocalized(clientAuth.name()), clientAuth); } } @@ -89,9 +91,9 @@ public class EncryptionOptions public static ClientAuth from(String value) { - if (VALUES.containsKey(value.toLowerCase())) + if (VALUES.containsKey(toLowerCaseLocalized(value))) { - return VALUES.get(value.toLowerCase()); + return VALUES.get(toLowerCaseLocalized(value)); } throw new ConfigurationException(value + " is not a valid ClientAuth option"); } @@ -183,7 +185,7 @@ public class EncryptionOptions Set valueSet = new HashSet<>(); ConfigKey[] values = values(); for(ConfigKey key: values) { - valueSet.add(key.getKeyName().toLowerCase()); + valueSet.add(toLowerCaseLocalized(key.getKeyName())); } return valueSet; } @@ -302,7 +304,7 @@ public class EncryptionOptions Set configKeys = ConfigKey.asSet(); for (Map.Entry entry : ssl_context_factory.parameters.entrySet()) { - if(configKeys.contains(entry.getKey().toLowerCase())) + if(configKeys.contains(toLowerCaseLocalized(entry.getKey()))) { throw new IllegalArgumentException("SslContextFactory "+ssl_context_factory.class_name+" should " + "configure '"+entry.getKey()+"' as encryption_options instead of" + diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java index 7eaa109f02..6e2fdcc22e 100644 --- a/src/java/org/apache/cassandra/cql3/CQL3Type.java +++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java @@ -42,6 +42,7 @@ import org.apache.cassandra.service.ClientState; import org.apache.cassandra.utils.ByteBufferUtil; import static java.util.stream.Collectors.toList; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public interface CQL3Type { @@ -139,7 +140,7 @@ public interface CQL3Type @Override public String toString() { - return super.toString().toLowerCase(); + return toLowerCaseLocalized(super.toString()); } } diff --git a/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java b/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java index e4da92218b..77cad3dd32 100644 --- a/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java +++ b/src/java/org/apache/cassandra/cql3/ColumnIdentifier.java @@ -19,7 +19,6 @@ package org.apache.cassandra.cql3; import java.nio.ByteBuffer; import java.util.List; -import java.util.Locale; import java.util.concurrent.ConcurrentMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -34,6 +33,8 @@ import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.ObjectSizes; import org.apache.cassandra.utils.memory.ByteBufferCloner; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * Represents an identifer for a CQL column definition. * TODO : should support light-weight mode without text representation for when not interned @@ -109,7 +110,7 @@ public class ColumnIdentifier implements IMeasurableMemory, Comparable expectedType, List defs, VariableSpecifications boundNames) diff --git a/src/java/org/apache/cassandra/cql3/selection/Selection.java b/src/java/org/apache/cassandra/cql3/selection/Selection.java index da87f2619a..743da6934e 100644 --- a/src/java/org/apache/cassandra/cql3/selection/Selection.java +++ b/src/java/org/apache/cassandra/cql3/selection/Selection.java @@ -37,6 +37,8 @@ import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.utils.JsonUtils; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public abstract class Selection { /** @@ -327,7 +329,7 @@ public abstract class Selection sb.append(", "); String columnName = spec.name.toString(); - if (!columnName.equals(columnName.toLowerCase(Locale.US))) + if (!columnName.equals(toLowerCaseLocalized(columnName))) columnName = "\"" + columnName + "\""; sb.append('"'); diff --git a/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java index a80e9ae693..9a51877c06 100644 --- a/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java +++ b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java @@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.exceptions.SyntaxException; import static java.lang.String.format; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public class PropertyDefinitions { @@ -113,7 +114,7 @@ public class PropertyDefinitions if (null == value) throw new IllegalArgumentException("value argument can't be null"); - String lowerCasedValue = value.toLowerCase(); + String lowerCasedValue = toLowerCaseLocalized(value); if (POSITIVE_PATTERN.matcher(lowerCasedValue).matches()) return true; diff --git a/src/java/org/apache/cassandra/db/ConsistencyLevel.java b/src/java/org/apache/cassandra/db/ConsistencyLevel.java index 7c21c1287a..73cdeb5c5c 100644 --- a/src/java/org/apache/cassandra/db/ConsistencyLevel.java +++ b/src/java/org/apache/cassandra/db/ConsistencyLevel.java @@ -17,9 +17,6 @@ */ package org.apache.cassandra.db; - -import java.util.Locale; - import com.carrotsearch.hppc.ObjectIntHashMap; import org.apache.cassandra.locator.Endpoints; import org.apache.cassandra.locator.InOurDc; @@ -31,6 +28,7 @@ import org.apache.cassandra.locator.NetworkTopologyStrategy; import org.apache.cassandra.transport.ProtocolException; import static org.apache.cassandra.locator.Replicas.addToCountPerDc; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public enum ConsistencyLevel { @@ -85,7 +83,7 @@ public enum ConsistencyLevel public static ConsistencyLevel fromString(String str) { - return valueOf(str.toUpperCase(Locale.US)); + return valueOf(toUpperCaseLocalized(str)); } public static int quorumFor(AbstractReplicationStrategy replicationStrategy) diff --git a/src/java/org/apache/cassandra/db/Directories.java b/src/java/org/apache/cassandra/db/Directories.java index cbe9d90322..c6e30c961d 100644 --- a/src/java/org/apache/cassandra/db/Directories.java +++ b/src/java/org/apache/cassandra/db/Directories.java @@ -79,6 +79,8 @@ import org.apache.cassandra.utils.DirectorySizeCalculator; import org.apache.cassandra.utils.JVMStabilityInspector; import org.apache.cassandra.utils.Pair; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * Encapsulate handling of paths to the data files. * @@ -755,11 +757,11 @@ public class Directories */ public static boolean isStoredInLocalSystemKeyspacesDataLocation(String keyspace, String table) { - String keyspaceName = keyspace.toLowerCase(); + String keyspaceName = toLowerCaseLocalized(keyspace); return SchemaConstants.LOCAL_SYSTEM_KEYSPACE_NAMES.contains(keyspaceName) && !(SchemaConstants.SYSTEM_KEYSPACE_NAME.equals(keyspaceName) - && SystemKeyspace.TABLES_SPLIT_ACROSS_MULTIPLE_DISKS.contains(table.toLowerCase())); + && SystemKeyspace.TABLES_SPLIT_ACROSS_MULTIPLE_DISKS.contains(toLowerCaseLocalized(table))); } public static class DataDirectory diff --git a/src/java/org/apache/cassandra/db/compaction/OperationType.java b/src/java/org/apache/cassandra/db/compaction/OperationType.java index 2a5ffc61e6..461067b458 100644 --- a/src/java/org/apache/cassandra/db/compaction/OperationType.java +++ b/src/java/org/apache/cassandra/db/compaction/OperationType.java @@ -17,6 +17,8 @@ */ package org.apache.cassandra.db.compaction; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public enum OperationType { /** Each modification here should be also applied to {@link org.apache.cassandra.tools.nodetool.Stop#compactionType} */ @@ -69,7 +71,7 @@ public enum OperationType OperationType(String type, boolean writesData, int priority) { this.type = type; - this.fileName = type.toLowerCase().replace(" ", ""); + this.fileName = toLowerCaseLocalized(type).replace(" ", ""); this.writesData = writesData; this.priority = priority; } diff --git a/src/java/org/apache/cassandra/db/compaction/unified/Controller.java b/src/java/org/apache/cassandra/db/compaction/unified/Controller.java index cd7a35d44d..5faab27027 100644 --- a/src/java/org/apache/cassandra/db/compaction/unified/Controller.java +++ b/src/java/org/apache/cassandra/db/compaction/unified/Controller.java @@ -25,18 +25,19 @@ import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import org.apache.cassandra.config.CassandraRelevantProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.compaction.UnifiedCompactionStrategy; import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.cassandra.utils.Overlaps; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.MonotonicClock; +import org.apache.cassandra.utils.Overlaps; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * The controller provides compaction parameters to the unified compaction strategy */ @@ -442,7 +443,7 @@ public class Controller sstableGrowthModifier = FBUtilities.parsePercent(options.get(SSTABLE_GROWTH_OPTION)); Overlaps.InclusionMethod inclusionMethod = options.containsKey(OVERLAP_INCLUSION_METHOD_OPTION) - ? Overlaps.InclusionMethod.valueOf(options.get(OVERLAP_INCLUSION_METHOD_OPTION).toUpperCase()) + ? Overlaps.InclusionMethod.valueOf(toUpperCaseLocalized(options.get(OVERLAP_INCLUSION_METHOD_OPTION))) : DEFAULT_OVERLAP_INCLUSION_METHOD; return new Controller(cfs, @@ -583,7 +584,7 @@ public class Controller { try { - Overlaps.InclusionMethod.valueOf(s.toUpperCase()); + Overlaps.InclusionMethod.valueOf(toUpperCaseLocalized(s)); } catch (IllegalArgumentException e) { diff --git a/src/java/org/apache/cassandra/db/lifecycle/LogRecord.java b/src/java/org/apache/cassandra/db/lifecycle/LogRecord.java index 34fd0daf91..5f45156eb6 100644 --- a/src/java/org/apache/cassandra/db/lifecycle/LogRecord.java +++ b/src/java/org/apache/cassandra/db/lifecycle/LogRecord.java @@ -46,6 +46,8 @@ import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.io.util.PathUtils; import org.apache.cassandra.utils.FBUtilities; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + /** * A decoded line in a transaction log file replica. * @@ -63,7 +65,7 @@ final class LogRecord public static Type fromPrefix(String prefix) { - return valueOf(prefix.toUpperCase()); + return valueOf(toUpperCaseLocalized(prefix)); } public boolean hasFile() diff --git a/src/java/org/apache/cassandra/db/marshal/CollectionType.java b/src/java/org/apache/cassandra/db/marshal/CollectionType.java index b4bcc78d40..8c39dbab4f 100644 --- a/src/java/org/apache/cassandra/db/marshal/CollectionType.java +++ b/src/java/org/apache/cassandra/db/marshal/CollectionType.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Iterator; import java.util.Objects; import java.util.function.Consumer; -import java.util.Locale; import org.apache.cassandra.cql3.CQL3Type; import org.apache.cassandra.cql3.ColumnSpecification; @@ -46,6 +45,8 @@ import org.apache.cassandra.utils.bytecomparable.ByteComparable; import org.apache.cassandra.utils.bytecomparable.ByteSource; import org.apache.cassandra.utils.bytecomparable.ByteSourceInverse; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * The abstract validator that is the base for maps, sets and lists (both frozen and non-frozen). * @@ -85,7 +86,7 @@ public abstract class CollectionType extends MultiElementType @Override public String toString() { - return super.toString().toLowerCase(Locale.US); + return toLowerCaseLocalized(super.toString()); } } @@ -142,7 +143,7 @@ public abstract class CollectionType extends MultiElementType public void validate(V value, ValueAccessor accessor) throws MarshalException { if (accessor.isEmpty(value)) - throw new MarshalException("Not enough bytes to read a " + kind.name().toLowerCase()); + throw new MarshalException("Not enough bytes to read a " + toLowerCaseLocalized(kind.name())); super.validate(value, accessor); } diff --git a/src/java/org/apache/cassandra/db/marshal/EmptyType.java b/src/java/org/apache/cassandra/db/marshal/EmptyType.java index 07ea3ff373..69ae2c2d4e 100644 --- a/src/java/org/apache/cassandra/db/marshal/EmptyType.java +++ b/src/java/org/apache/cassandra/db/marshal/EmptyType.java @@ -39,6 +39,7 @@ import org.apache.cassandra.utils.bytecomparable.ByteSource; import org.apache.cassandra.utils.NoSpamLogger; import static org.apache.cassandra.config.CassandraRelevantProperties.SERIALIZATION_EMPTY_TYPE_NONEMPTY_BEHAVIOR; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * A type that only accept empty data. @@ -59,7 +60,7 @@ public class EmptyType extends AbstractType return NonEmptyWriteBehavior.FAIL; try { - return NonEmptyWriteBehavior.valueOf(value.toUpperCase().trim()); + return NonEmptyWriteBehavior.valueOf(toUpperCaseLocalized(value).trim()); } catch (Exception e) { diff --git a/src/java/org/apache/cassandra/db/marshal/UserType.java b/src/java/org/apache/cassandra/db/marshal/UserType.java index 7addfef63d..bbd16e36d1 100644 --- a/src/java/org/apache/cassandra/db/marshal/UserType.java +++ b/src/java/org/apache/cassandra/db/marshal/UserType.java @@ -50,6 +50,7 @@ import static com.google.common.collect.Iterables.any; import static com.google.common.collect.Iterables.transform; import static org.apache.cassandra.config.CassandraRelevantProperties.TYPE_UDT_CONFLICT_BEHAVIOR; import static org.apache.cassandra.cql3.ColumnIdentifier.maybeQuote; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * A user defined type. @@ -274,7 +275,7 @@ public class UserType extends TupleType implements SchemaElement sb.append(", "); String name = stringFieldNames.get(i); - if (!name.equals(name.toLowerCase(Locale.US))) + if (!name.equals(toLowerCaseLocalized(name))) name = "\"" + name + "\""; sb.append('"'); diff --git a/src/java/org/apache/cassandra/db/virtual/ClientsTable.java b/src/java/org/apache/cassandra/db/virtual/ClientsTable.java index 8f99f3a771..370808eec8 100644 --- a/src/java/org/apache/cassandra/db/virtual/ClientsTable.java +++ b/src/java/org/apache/cassandra/db/virtual/ClientsTable.java @@ -32,6 +32,8 @@ import org.apache.cassandra.metrics.ClientMetrics; import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.transport.ConnectedClient; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + final class ClientsTable extends AbstractVirtualTable { private static final String ADDRESS = "address"; @@ -88,7 +90,7 @@ final class ClientsTable extends AbstractVirtualTable result.row(remoteAddress.getAddress(), remoteAddress.getPort()) .column(HOSTNAME, remoteAddress.getHostName()) .column(USERNAME, client.username().orElse(null)) - .column(CONNECTION_STAGE, client.stage().toString().toLowerCase()) + .column(CONNECTION_STAGE, toLowerCaseLocalized(client.stage().toString())) .column(PROTOCOL_VERSION, client.protocolVersion()) .column(CLIENT_OPTIONS, client.clientOptions().orElse(null)) .column(DRIVER_NAME, client.driverName().orElse(null)) diff --git a/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java b/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java index 56eacf5b3e..c5079d73c0 100644 --- a/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java +++ b/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java @@ -85,6 +85,7 @@ import org.apache.cassandra.utils.Pair; import static org.apache.cassandra.db.rows.Cell.NO_DELETION_TIME; import static org.apache.cassandra.utils.FBUtilities.camelToSnake; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * This is a virtual table that iteratively builds rows using a data set provided by internal collection. @@ -255,7 +256,7 @@ public class CollectionVirtualTableAdapter implements VirtualTable Pattern pattern = Pattern.compile("^[A-Z1-9_]+$"); // Contains only uppercase letters, numbers and underscores, so it's already snake case. if (pattern.matcher(camel).matches()) - return camel.toLowerCase(); + return toLowerCaseLocalized(camel); // Some special cases must be handled manually. String modifiedCamel = camel; diff --git a/src/java/org/apache/cassandra/db/virtual/GossipInfoTable.java b/src/java/org/apache/cassandra/db/virtual/GossipInfoTable.java index bd612c6c21..2051e6ef7b 100644 --- a/src/java/org/apache/cassandra/db/virtual/GossipInfoTable.java +++ b/src/java/org/apache/cassandra/db/virtual/GossipInfoTable.java @@ -35,6 +35,7 @@ import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.schema.TableMetadata; import static org.apache.cassandra.gms.ApplicationState.TOKENS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * A {@link VirtualTable} that return the Gossip information in tabular format. @@ -101,10 +102,10 @@ final class GossipInfoTable extends AbstractVirtualTable .column(HEARTBEAT, getHeartBeat(localState)); for (ApplicationState state : STATES_FOR_VALUES) - dataSet.column(state.name().toLowerCase(), getValue(localState, state)); + dataSet.column(toLowerCaseLocalized(state.name()), getValue(localState, state)); for (ApplicationState state : STATES_FOR_VERSIONS) - dataSet.column(state.name().toLowerCase() + "_version", getVersion(localState, state)); + dataSet.column(toLowerCaseLocalized(state.name()) + "_version", getVersion(localState, state)); } return result; } @@ -178,10 +179,10 @@ final class GossipInfoTable extends AbstractVirtualTable .addRegularColumn(HEARTBEAT, Int32Type.instance); for (ApplicationState state : STATES_FOR_VALUES) - builder.addRegularColumn(state.name().toLowerCase(), UTF8Type.instance); + builder.addRegularColumn(toLowerCaseLocalized(state.name()), UTF8Type.instance); for (ApplicationState state : STATES_FOR_VERSIONS) - builder.addRegularColumn(state.name().toLowerCase() + "_version", Int32Type.instance); + builder.addRegularColumn(toLowerCaseLocalized(state.name()) + "_version", Int32Type.instance); return builder.build(); } diff --git a/src/java/org/apache/cassandra/db/virtual/LocalRepairTables.java b/src/java/org/apache/cassandra/db/virtual/LocalRepairTables.java index b88502988e..1c8c24b171 100644 --- a/src/java/org/apache/cassandra/db/virtual/LocalRepairTables.java +++ b/src/java/org/apache/cassandra/db/virtual/LocalRepairTables.java @@ -49,6 +49,8 @@ import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.service.ActiveRepairService; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class LocalRepairTables { private LocalRepairTables() @@ -385,7 +387,7 @@ public class LocalRepairTables private static String timestampColumnName(Enum e) { - return timestampColumnName(e.name().toLowerCase()); + return timestampColumnName(toLowerCaseLocalized(e.name())); } private static String timestampColumnName(String e) @@ -431,7 +433,7 @@ public class LocalRepairTables T currentState = state.getStatus(); State.Result result = state.getResult(); - ds.column("status", result != null ? result.kind.name().toLowerCase() : currentState == null ? "init" : currentState.name().toLowerCase()); + ds.column("status", result != null ? toLowerCaseLocalized(result.kind.name()) : currentState == null ? "init" : toLowerCaseLocalized(currentState.name())); for (Map.Entry e : state.getStateTimesMillis().entrySet()) { if (e.getValue().longValue() != 0) diff --git a/src/java/org/apache/cassandra/db/virtual/SSTableTasksTable.java b/src/java/org/apache/cassandra/db/virtual/SSTableTasksTable.java index e2f38f8e92..a2b80d9b8f 100644 --- a/src/java/org/apache/cassandra/db/virtual/SSTableTasksTable.java +++ b/src/java/org/apache/cassandra/db/virtual/SSTableTasksTable.java @@ -27,6 +27,8 @@ import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.dht.LocalPartitioner; import org.apache.cassandra.schema.TableMetadata; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + final class SSTableTasksTable extends AbstractVirtualTable { private final static String KEYSPACE_NAME = "keyspace_name"; @@ -74,11 +76,11 @@ final class SSTableTasksTable extends AbstractVirtualTable task.getTable().orElse("*"), task.getTaskId()) .column(COMPLETION_RATIO, completionRatio) - .column(KIND, task.getTaskType().toString().toLowerCase()) + .column(KIND, toLowerCaseLocalized(task.getTaskType().toString())) .column(PROGRESS, completed) .column(SSTABLES, task.getSSTables().size()) .column(TOTAL, total) - .column(UNIT, task.getUnit().toString().toLowerCase()) + .column(UNIT, toLowerCaseLocalized(task.getUnit().toString())) .column(TARGET_DIRECTORY, task.targetDirectory()); } diff --git a/src/java/org/apache/cassandra/db/virtual/StreamingVirtualTable.java b/src/java/org/apache/cassandra/db/virtual/StreamingVirtualTable.java index f01e79956d..acfcede374 100644 --- a/src/java/org/apache/cassandra/db/virtual/StreamingVirtualTable.java +++ b/src/java/org/apache/cassandra/db/virtual/StreamingVirtualTable.java @@ -28,6 +28,8 @@ import org.apache.cassandra.streaming.StreamManager; import org.apache.cassandra.streaming.StreamingState; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + import static org.apache.cassandra.cql3.statements.schema.CreateTableStatement.parse; public class StreamingVirtualTable extends AbstractVirtualTable @@ -60,7 +62,7 @@ public class StreamingVirtualTable extends AbstractVirtualTable { StringBuilder sb = new StringBuilder(); for (StreamingState.Status state : StreamingState.Status.values()) - sb.append(" status_").append(state.name().toLowerCase()).append("_timestamp timestamp,\n"); + sb.append(" status_").append(toLowerCaseLocalized(state.name())).append("_timestamp timestamp,\n"); return sb.toString(); } @@ -91,13 +93,13 @@ public class StreamingVirtualTable extends AbstractVirtualTable ds.column("follower", state.follower()); ds.column("operation", state.operation().getDescription()); ds.column("peers", state.peers().stream().map(Object::toString).collect(Collectors.toList())); - ds.column("status", state.status().name().toLowerCase()); + ds.column("status", toLowerCaseLocalized(state.status().name())); ds.column("progress_percentage", round(state.progress() * 100)); ds.column("duration_millis", state.durationMillis()); ds.column("failure_cause", state.failureCause()); ds.column("success_message", state.successMessage()); for (Map.Entry e : state.stateTimesMillis().entrySet()) - ds.column("status_" + e.getKey().name().toLowerCase() + "_timestamp", new Date(e.getValue())); + ds.column("status_" + toLowerCaseLocalized(e.getKey().name()) + "_timestamp", new Date(e.getValue())); state.sessions().update(ds); } diff --git a/src/java/org/apache/cassandra/db/virtual/VirtualSchemaKeyspace.java b/src/java/org/apache/cassandra/db/virtual/VirtualSchemaKeyspace.java index bb5a430f0d..43e373d6e3 100644 --- a/src/java/org/apache/cassandra/db/virtual/VirtualSchemaKeyspace.java +++ b/src/java/org/apache/cassandra/db/virtual/VirtualSchemaKeyspace.java @@ -29,6 +29,7 @@ import org.apache.cassandra.schema.TableMetadata; import static org.apache.cassandra.schema.SchemaConstants.VIRTUAL_SCHEMA; import static org.apache.cassandra.schema.TableMetadata.builder; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public final class VirtualSchemaKeyspace extends VirtualKeyspace { @@ -136,9 +137,9 @@ public final class VirtualSchemaKeyspace extends VirtualKeyspace for (ColumnMetadata column : table.columns()) { result.row(column.ksName, column.cfName, column.name.toString()) - .column(CLUSTERING_ORDER, column.clusteringOrder().toString().toLowerCase()) + .column(CLUSTERING_ORDER, toLowerCaseLocalized(column.clusteringOrder().toString())) .column(COLUMN_NAME_BYTES, column.name.bytes) - .column(KIND, column.kind.toString().toLowerCase()) + .column(KIND, toLowerCaseLocalized(column.kind.toString())) .column(POSITION, column.position()) .column(TYPE, column.type.asCQL3Type().toString()); } diff --git a/src/java/org/apache/cassandra/index/sai/analyzer/filter/BasicFilters.java b/src/java/org/apache/cassandra/index/sai/analyzer/filter/BasicFilters.java index b70fbae9da..f81824f8ea 100644 --- a/src/java/org/apache/cassandra/index/sai/analyzer/filter/BasicFilters.java +++ b/src/java/org/apache/cassandra/index/sai/analyzer/filter/BasicFilters.java @@ -23,6 +23,8 @@ import java.util.Locale; import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class BasicFilters { private static final Locale DEFAULT_LOCALE = Locale.getDefault(); @@ -39,7 +41,7 @@ public class BasicFilters @Override public String process(String input) { - return input.toLowerCase(locale); + return toLowerCaseLocalized(input, locale); } } diff --git a/src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java b/src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java index fe9be1c98d..c6b0607437 100644 --- a/src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java +++ b/src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java @@ -28,6 +28,7 @@ import org.apache.cassandra.index.sai.disk.v1.vector.OptimizeFor; import org.apache.cassandra.index.sai.utils.IndexTermType; import static org.apache.cassandra.config.CassandraRelevantProperties.SAI_VECTOR_SEARCH_MAX_TOP_K; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * Per-index config for storage-attached index writers. @@ -151,7 +152,7 @@ public class IndexWriterConfig } if (options.containsKey(SIMILARITY_FUNCTION)) { - String option = options.get(SIMILARITY_FUNCTION).toUpperCase(); + String option = toUpperCaseLocalized(options.get(SIMILARITY_FUNCTION)); try { similarityFunction = VectorSimilarityFunction.valueOf(option); @@ -164,7 +165,7 @@ public class IndexWriterConfig } if (options.containsKey(OPTIMIZE_FOR)) { - String option = options.get(OPTIMIZE_FOR).toUpperCase(); + String option = toUpperCaseLocalized(options.get(OPTIMIZE_FOR)); try { optimizeFor = OptimizeFor.valueOf(option); diff --git a/src/java/org/apache/cassandra/index/sai/disk/v1/vector/OptimizeFor.java b/src/java/org/apache/cassandra/index/sai/disk/v1/vector/OptimizeFor.java index 51e58b37df..e2a566ea8b 100644 --- a/src/java/org/apache/cassandra/index/sai/disk/v1/vector/OptimizeFor.java +++ b/src/java/org/apache/cassandra/index/sai/disk/v1/vector/OptimizeFor.java @@ -21,6 +21,7 @@ package org.apache.cassandra.index.sai.disk.v1.vector; import java.util.function.Function; import static java.lang.Math.pow; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * Allows the vector index searches to be optimised for latency or recall. This is used by the @@ -47,6 +48,6 @@ public enum OptimizeFor public static OptimizeFor fromString(String value) { - return valueOf(value.toUpperCase()); + return valueOf(toUpperCaseLocalized(value)); } } diff --git a/src/java/org/apache/cassandra/index/sasi/analyzer/filter/BasicResultFilters.java b/src/java/org/apache/cassandra/index/sasi/analyzer/filter/BasicResultFilters.java index 2b949b898b..bf0776410c 100644 --- a/src/java/org/apache/cassandra/index/sasi/analyzer/filter/BasicResultFilters.java +++ b/src/java/org/apache/cassandra/index/sasi/analyzer/filter/BasicResultFilters.java @@ -19,6 +19,9 @@ package org.apache.cassandra.index.sasi.analyzer.filter; import java.util.Locale; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + /** * Basic/General Token Filters */ @@ -42,7 +45,7 @@ public class BasicResultFilters public String process(String input) throws Exception { - return input.toLowerCase(locale); + return toLowerCaseLocalized(input, locale); } } @@ -62,7 +65,7 @@ public class BasicResultFilters public String process(String input) throws Exception { - return input.toUpperCase(locale); + return toUpperCaseLocalized(input, locale); } } diff --git a/src/java/org/apache/cassandra/index/sasi/disk/OnDiskIndexBuilder.java b/src/java/org/apache/cassandra/index/sasi/disk/OnDiskIndexBuilder.java index 9071e10884..6930055048 100644 --- a/src/java/org/apache/cassandra/index/sasi/disk/OnDiskIndexBuilder.java +++ b/src/java/org/apache/cassandra/index/sasi/disk/OnDiskIndexBuilder.java @@ -43,6 +43,8 @@ import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class OnDiskIndexBuilder { private static final Logger logger = LoggerFactory.getLogger(OnDiskIndexBuilder.class); @@ -62,7 +64,7 @@ public class OnDiskIndexBuilder public static Mode mode(String mode) { - return Mode.valueOf(mode.toUpperCase()); + return Mode.valueOf(toUpperCaseLocalized(mode)); } public boolean supports(Op op) diff --git a/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java b/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java index dcd883a718..8cf83f5208 100644 --- a/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java +++ b/src/java/org/apache/cassandra/metrics/CassandraMetricsRegistry.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -74,6 +73,7 @@ import static java.util.Optional.ofNullable; import static org.apache.cassandra.db.virtual.CollectionVirtualTableAdapter.createSinglePartitionedKeyFiltered; import static org.apache.cassandra.db.virtual.CollectionVirtualTableAdapter.createSinglePartitionedValueFiltered; import static org.apache.cassandra.schema.SchemaConstants.VIRTUAL_METRICS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * Dropwizard metrics registry extension for Cassandra, as of for now uses the latest version of Dropwizard metrics @@ -810,7 +810,7 @@ public class CassandraMetricsRegistry extends MetricRegistry private String calculateRateUnit(TimeUnit unit) { - final String s = unit.toString().toLowerCase(Locale.US); + final String s = toLowerCaseLocalized(unit.toString()); return s.substring(0, s.length() - 1); } } @@ -861,7 +861,7 @@ public class CassandraMetricsRegistry extends MetricRegistry { super(metric, objectName, rateUnit); this.metric = metric; - this.durationUnit = durationUnit.toString().toLowerCase(Locale.US); + this.durationUnit = toLowerCaseLocalized(durationUnit.toString()); } @Override diff --git a/src/java/org/apache/cassandra/schema/CQLTypeParser.java b/src/java/org/apache/cassandra/schema/CQLTypeParser.java index c79de88155..ef1af7fda3 100644 --- a/src/java/org/apache/cassandra/schema/CQLTypeParser.java +++ b/src/java/org/apache/cassandra/schema/CQLTypeParser.java @@ -24,6 +24,8 @@ import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.UserType; import static org.apache.cassandra.utils.ByteBufferUtil.bytes; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public final class CQLTypeParser { @@ -33,17 +35,17 @@ public final class CQLTypeParser { ImmutableSet.Builder builder = ImmutableSet.builder(); for (CQL3Type.Native primitive : CQL3Type.Native.values()) - builder.add(primitive.name().toLowerCase()); + builder.add(toLowerCaseLocalized(primitive.name())); PRIMITIVE_TYPES = builder.build(); } public static AbstractType parse(String keyspace, String unparsed, Types userTypes) { - String lowercased = unparsed.toLowerCase(); + String lowercased = toLowerCaseLocalized(unparsed); // fast path for the common case of a primitive type if (PRIMITIVE_TYPES.contains(lowercased)) - return CQL3Type.Native.valueOf(unparsed.toUpperCase()).getType(); + return CQL3Type.Native.valueOf(toUpperCaseLocalized(unparsed)).getType(); // special-case top-level UDTs UserType udt = userTypes.getNullable(bytes(lowercased)); diff --git a/src/java/org/apache/cassandra/schema/CachingParams.java b/src/java/org/apache/cassandra/schema/CachingParams.java index 1976835c89..f06eadb8db 100644 --- a/src/java/org/apache/cassandra/schema/CachingParams.java +++ b/src/java/org/apache/cassandra/schema/CachingParams.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.cassandra.exceptions.ConfigurationException; import static java.lang.String.format; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; // CQL: {'keys' : 'ALL'|'NONE', 'rows_per_partition': '200'|'NONE'|'ALL'} public final class CachingParams @@ -40,7 +41,7 @@ public final class CachingParams @Override public String toString() { - return name().toLowerCase(); + return toLowerCaseLocalized(name()); } } diff --git a/src/java/org/apache/cassandra/schema/CompactionParams.java b/src/java/org/apache/cassandra/schema/CompactionParams.java index 7da6b50280..e082be487b 100644 --- a/src/java/org/apache/cassandra/schema/CompactionParams.java +++ b/src/java/org/apache/cassandra/schema/CompactionParams.java @@ -42,6 +42,8 @@ import org.apache.cassandra.utils.FBUtilities; import static java.lang.String.format; import static org.apache.cassandra.config.CassandraRelevantProperties.DEFAULT_PROVIDE_OVERLAPPING_TOMBSTONES; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public final class CompactionParams { @@ -58,7 +60,7 @@ public final class CompactionParams @Override public String toString() { - return name().toLowerCase(); + return toLowerCaseLocalized(name()); } } @@ -123,8 +125,8 @@ public final class CompactionParams boolean isEnabled = options.containsKey(Option.ENABLED.toString()) ? Boolean.parseBoolean(options.get(Option.ENABLED.toString())) : DEFAULT_ENABLED; - String overlappingTombstoneParm = options.getOrDefault(Option.PROVIDE_OVERLAPPING_TOMBSTONES.toString(), - DEFAULT_PROVIDE_OVERLAPPING_TOMBSTONES_PROPERTY_VALUE.toString()).toUpperCase(); + String overlappingTombstoneParm = toUpperCaseLocalized(options.getOrDefault(Option.PROVIDE_OVERLAPPING_TOMBSTONES.toString(), + DEFAULT_PROVIDE_OVERLAPPING_TOMBSTONES_PROPERTY_VALUE.toString())); Optional tombstoneOptional = TombstoneOption.forName(overlappingTombstoneParm); if (!tombstoneOptional.isPresent()) { diff --git a/src/java/org/apache/cassandra/schema/IndexMetadata.java b/src/java/org/apache/cassandra/schema/IndexMetadata.java index fb94c56f01..1f73a5f98c 100644 --- a/src/java/org/apache/cassandra/schema/IndexMetadata.java +++ b/src/java/org/apache/cassandra/schema/IndexMetadata.java @@ -49,6 +49,7 @@ import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.UUIDSerializer; import static org.apache.cassandra.db.TypeSizes.sizeof; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * An immutable representation of secondary index metadata. @@ -72,7 +73,7 @@ public final class IndexMetadata static { indexNameAliases.put(StorageAttachedIndex.NAME, StorageAttachedIndex.class.getCanonicalName()); - indexNameAliases.put(StorageAttachedIndex.class.getSimpleName().toLowerCase(), StorageAttachedIndex.class.getCanonicalName()); + indexNameAliases.put(toLowerCaseLocalized(StorageAttachedIndex.class.getSimpleName()), StorageAttachedIndex.class.getCanonicalName()); indexNameAliases.put(SASIIndex.class.getSimpleName(), SASIIndex.class.getCanonicalName()); } @@ -159,7 +160,7 @@ public final class IndexMetadata if (isCustom()) { String className = options.get(IndexTarget.CUSTOM_INDEX_OPTION_NAME); - return indexNameAliases.getOrDefault(className.toLowerCase(), className); + return indexNameAliases.getOrDefault(toLowerCaseLocalized(className), className); } return CassandraIndex.class.getName(); } diff --git a/src/java/org/apache/cassandra/schema/KeyspaceParams.java b/src/java/org/apache/cassandra/schema/KeyspaceParams.java index 9cfaaa17f6..76516334b8 100644 --- a/src/java/org/apache/cassandra/schema/KeyspaceParams.java +++ b/src/java/org/apache/cassandra/schema/KeyspaceParams.java @@ -32,6 +32,8 @@ import org.apache.cassandra.tcm.ClusterMetadata; import org.apache.cassandra.tcm.serialization.MetadataSerializer; import org.apache.cassandra.tcm.serialization.Version; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * An immutable class representing keyspace parameters (durability and replication). */ @@ -57,7 +59,7 @@ public final class KeyspaceParams @Override public String toString() { - return name().toLowerCase(); + return toLowerCaseLocalized(name()); } } diff --git a/src/java/org/apache/cassandra/schema/SchemaConstants.java b/src/java/org/apache/cassandra/schema/SchemaConstants.java index bc733d367e..9a5e8844b2 100644 --- a/src/java/org/apache/cassandra/schema/SchemaConstants.java +++ b/src/java/org/apache/cassandra/schema/SchemaConstants.java @@ -32,6 +32,8 @@ import org.apache.cassandra.db.Digest; import org.apache.cassandra.db.SystemKeyspace; import org.apache.cassandra.tracing.TraceKeyspace; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * When adding new String keyspace names here, double check if it needs to be added to PartitionDenylist.canDenylistKeyspace */ @@ -93,7 +95,7 @@ public final class SchemaConstants */ public static boolean isLocalSystemKeyspace(String keyspaceName) { - return LOCAL_SYSTEM_KEYSPACE_NAMES.contains(keyspaceName.toLowerCase()) || isVirtualSystemKeyspace(keyspaceName); + return LOCAL_SYSTEM_KEYSPACE_NAMES.contains(toLowerCaseLocalized(keyspaceName)) || isVirtualSystemKeyspace(keyspaceName); } /** @@ -101,7 +103,7 @@ public final class SchemaConstants */ public static boolean isReplicatedSystemKeyspace(String keyspaceName) { - return REPLICATED_SYSTEM_KEYSPACE_NAMES.contains(keyspaceName.toLowerCase()); + return REPLICATED_SYSTEM_KEYSPACE_NAMES.contains(toLowerCaseLocalized(keyspaceName)); } /** @@ -110,7 +112,7 @@ public final class SchemaConstants */ public static boolean isVirtualSystemKeyspace(String keyspaceName) { - return VIRTUAL_SYSTEM_KEYSPACE_NAMES.contains(keyspaceName.toLowerCase()); + return VIRTUAL_SYSTEM_KEYSPACE_NAMES.contains(toLowerCaseLocalized(keyspaceName)); } /** diff --git a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java index 8b748050e3..a6877cc631 100644 --- a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java +++ b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java @@ -27,7 +27,7 @@ import javax.annotation.concurrent.NotThreadSafe; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.*; -import com.google.common.collect.Maps; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,6 +62,8 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_FLUSH import static org.apache.cassandra.cql3.QueryProcessor.executeInternal; import static org.apache.cassandra.cql3.QueryProcessor.executeOnceInternal; import static org.apache.cassandra.schema.SchemaKeyspaceTables.*; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; import static org.apache.cassandra.utils.Simulate.With.GLOBAL_CLOCK; /** @@ -694,9 +696,9 @@ public final class SchemaKeyspace builder.update(Columns) .row(table.name, column.name.toString()) .add("column_name_bytes", column.name.bytes) - .add("kind", column.kind.toString().toLowerCase()) + .add("kind", toLowerCaseLocalized(column.kind.toString())) .add("position", column.position()) - .add("clustering_order", column.clusteringOrder().toString().toLowerCase()) + .add("clustering_order", toLowerCaseLocalized(column.clusteringOrder().toString())) .add("type", type.asCQL3Type().toString()); ColumnMask mask = column.getMask(); @@ -758,7 +760,7 @@ public final class SchemaKeyspace .row(table.name, column.column.name.toString()) .add("dropped_time", new Date(TimeUnit.MICROSECONDS.toMillis(column.droppedTime))) .add("type", column.column.type.asCQL3Type().toString()) - .add("kind", column.column.kind.toString().toLowerCase()); + .add("kind", toLowerCaseLocalized(column.column.kind.toString())); } private static void dropDroppedColumnFromSchemaMutation(TableMetadata table, DroppedColumn column, Mutation.SimpleBuilder builder) @@ -1075,10 +1077,10 @@ public final class SchemaKeyspace String keyspace = row.getString("keyspace_name"); String table = row.getString("table_name"); - ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(row.getString("kind").toUpperCase()); + ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(toUpperCaseLocalized(row.getString("kind"))); int position = row.getInt("position"); - ClusteringOrder order = ClusteringOrder.valueOf(row.getString("clustering_order").toUpperCase()); + ClusteringOrder order = ClusteringOrder.valueOf(toUpperCaseLocalized(row.getString("clustering_order"))); AbstractType type = CQLTypeParser.parse(keyspace, row.getString("type"), types); if (order == ClusteringOrder.DESC) @@ -1159,7 +1161,7 @@ public final class SchemaKeyspace */ AbstractType type = CQLTypeParser.parse(keyspace, row.getString("type"), org.apache.cassandra.schema.Types.none()); ColumnMetadata.Kind kind = row.has("kind") - ? ColumnMetadata.Kind.valueOf(row.getString("kind").toUpperCase()) + ? ColumnMetadata.Kind.valueOf(toUpperCaseLocalized(row.getString("kind"))) : ColumnMetadata.Kind.REGULAR; assert kind == ColumnMetadata.Kind.REGULAR || kind == ColumnMetadata.Kind.STATIC : "Unexpected dropped column kind: " + kind; diff --git a/src/java/org/apache/cassandra/schema/TableParams.java b/src/java/org/apache/cassandra/schema/TableParams.java index 2da45e5f97..6903179525 100644 --- a/src/java/org/apache/cassandra/schema/TableParams.java +++ b/src/java/org/apache/cassandra/schema/TableParams.java @@ -44,6 +44,7 @@ import static java.lang.String.format; import static java.util.stream.Collectors.toMap; import static org.apache.cassandra.schema.TableParams.Option.*; import static org.apache.cassandra.db.TypeSizes.sizeof; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public final class TableParams { @@ -73,7 +74,7 @@ public final class TableParams @Override public String toString() { - return name().toLowerCase(); + return toLowerCaseLocalized(name()); } } diff --git a/src/java/org/apache/cassandra/security/JKSKeyProvider.java b/src/java/org/apache/cassandra/security/JKSKeyProvider.java index 2fddf5e55f..eedacba39f 100644 --- a/src/java/org/apache/cassandra/security/JKSKeyProvider.java +++ b/src/java/org/apache/cassandra/security/JKSKeyProvider.java @@ -29,6 +29,8 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.TransparentDataEncryptionOptions; import org.apache.cassandra.io.util.File; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * A {@code KeyProvider} that retrieves keys from a java keystore. */ @@ -64,7 +66,7 @@ public class JKSKeyProvider implements KeyProvider { // there's a lovely behavior with jceks files that all aliases are lower-cased if (isJceks) - keyAlias = keyAlias.toLowerCase(); + keyAlias = toLowerCaseLocalized(keyAlias); Key key; try diff --git a/src/java/org/apache/cassandra/security/SSLFactory.java b/src/java/org/apache/cassandra/security/SSLFactory.java index c55e970b4f..a9b4be9d5c 100644 --- a/src/java/org/apache/cassandra/security/SSLFactory.java +++ b/src/java/org/apache/cassandra/security/SSLFactory.java @@ -48,6 +48,7 @@ import org.apache.cassandra.security.ISslContextFactory.SocketType; import static org.apache.cassandra.config.CassandraRelevantProperties.DISABLE_TCACTIVE_OPENSSL; import static org.apache.cassandra.config.EncryptionOptions.ClientAuth.REQUIRED; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * A Factory for providing and setting up client {@link SSLSocket}s. Also provides @@ -337,7 +338,7 @@ public final class SSLFactory if (settingDescription != null) { logger.warn("Dropping unsupported cipher_suite {} from {} configuration", - c, settingDescription.toLowerCase()); + c, toLowerCaseLocalized(settingDescription)); } } } diff --git a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java index 74b790bf29..6d38f2a781 100644 --- a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java +++ b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java @@ -23,7 +23,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Locale; import java.util.function.Consumer; import com.google.common.collect.Range; @@ -34,6 +33,8 @@ import org.apache.cassandra.db.marshal.ValueAccessor; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.utils.ByteBufferUtil; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public abstract class CollectionSerializer extends TypeSerializer { protected abstract List serializeValues(T value); @@ -110,7 +111,7 @@ public abstract class CollectionSerializer extends TypeSerializer */ private String getCollectionName() { - return getType().getSimpleName().toLowerCase(Locale.US); + return toLowerCaseLocalized(getType().getSimpleName()); } /** diff --git a/src/java/org/apache/cassandra/service/StartupChecks.java b/src/java/org/apache/cassandra/service/StartupChecks.java index 5dc11a6c6b..91a95a4e10 100644 --- a/src/java/org/apache/cassandra/service/StartupChecks.java +++ b/src/java/org/apache/cassandra/service/StartupChecks.java @@ -80,6 +80,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_KER import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_VERSION; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_VM_NAME; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * Verifies that the system and environment is in a fit state to be started. @@ -217,7 +218,7 @@ public class StartupChecks { try { - if (affectedFileSystemTypes.contains(Files.getFileStore(path).type().toLowerCase())) + if (affectedFileSystemTypes.contains(toLowerCaseLocalized(Files.getFileStore(path).type()))) affectedPaths.add(path); } catch (IOException e) diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java index 055ce391c7..e62c1bb3bd 100644 --- a/src/java/org/apache/cassandra/service/StorageProxy.java +++ b/src/java/org/apache/cassandra/service/StorageProxy.java @@ -177,6 +177,7 @@ import static org.apache.cassandra.service.paxos.v1.PrepareVerbHandler.doPrepare import static org.apache.cassandra.service.paxos.v1.ProposeVerbHandler.doPropose; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID; import static org.apache.cassandra.utils.concurrent.CountDownLatch.newCountDownLatch; import static org.apache.commons.lang3.StringUtils.join; @@ -2835,7 +2836,7 @@ public class StorageProxy implements StorageProxyMBean public String setIdealConsistencyLevel(String cl) { ConsistencyLevel original = DatabaseDescriptor.getIdealConsistencyLevel(); - ConsistencyLevel newCL = ConsistencyLevel.valueOf(cl.trim().toUpperCase()); + ConsistencyLevel newCL = ConsistencyLevel.valueOf(toUpperCaseLocalized(cl.trim())); DatabaseDescriptor.setIdealConsistencyLevel(newCL); return String.format("Updating ideal consistency level new value: %s old value %s", newCL, original.toString()); } diff --git a/src/java/org/apache/cassandra/service/paxos/ContentionStrategy.java b/src/java/org/apache/cassandra/service/paxos/ContentionStrategy.java index 7f38567f6a..59ee550512 100644 --- a/src/java/org/apache/cassandra/service/paxos/ContentionStrategy.java +++ b/src/java/org/apache/cassandra/service/paxos/ContentionStrategy.java @@ -52,6 +52,7 @@ import static org.apache.cassandra.metrics.ClientRequestsMetricsHolder.casReadMe import static org.apache.cassandra.metrics.ClientRequestsMetricsHolder.casWriteMetrics; import static org.apache.cassandra.utils.Clock.Global.nanoTime; import static org.apache.cassandra.utils.Clock.waitUntil; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** *

A strategy for making back-off decisions for Paxos operations that fail to make progress because of other paxos operations. @@ -369,7 +370,7 @@ public class ContentionStrategy Type(String traceTitle) { this.traceTitle = traceTitle; - this.lowercase = name().toLowerCase(); + this.lowercase = toLowerCaseLocalized(name()); } } diff --git a/src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java b/src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java index fedec23f40..226f4f1441 100644 --- a/src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java +++ b/src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java @@ -27,6 +27,8 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.metrics.SnapshottingTimer; import org.apache.cassandra.schema.TableParams; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class HybridSpeculativeRetryPolicy implements SpeculativeRetryPolicy { private static final Pattern PATTERN = @@ -128,7 +130,7 @@ public class HybridSpeculativeRetryPolicy implements SpeculativeRetryPolicy SpeculativeRetryPolicy policy1 = value1 instanceof PercentileSpeculativeRetryPolicy ? value1 : value2; SpeculativeRetryPolicy policy2 = value1 instanceof FixedSpeculativeRetryPolicy ? value1 : value2; - Function function = Function.valueOf(matcher.group("fun").toUpperCase()); + Function function = Function.valueOf(toUpperCaseLocalized(matcher.group("fun"))); return new HybridSpeculativeRetryPolicy((PercentileSpeculativeRetryPolicy) policy1, (FixedSpeculativeRetryPolicy) policy2, function); } diff --git a/src/java/org/apache/cassandra/service/reads/repair/ReadRepairStrategy.java b/src/java/org/apache/cassandra/service/reads/repair/ReadRepairStrategy.java index 975b8217d2..22615494a7 100644 --- a/src/java/org/apache/cassandra/service/reads/repair/ReadRepairStrategy.java +++ b/src/java/org/apache/cassandra/service/reads/repair/ReadRepairStrategy.java @@ -23,6 +23,8 @@ import org.apache.cassandra.locator.Endpoints; import org.apache.cassandra.locator.ReplicaPlan; import org.apache.cassandra.transport.Dispatcher; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public enum ReadRepairStrategy implements ReadRepair.Factory { NONE @@ -45,6 +47,6 @@ public enum ReadRepairStrategy implements ReadRepair.Factory public static ReadRepairStrategy fromString(String s) { - return valueOf(s.toUpperCase()); + return valueOf(toUpperCaseLocalized(s)); } } diff --git a/src/java/org/apache/cassandra/streaming/StreamResultFuture.java b/src/java/org/apache/cassandra/streaming/StreamResultFuture.java index 5277b9de73..6d3e1ca6c1 100644 --- a/src/java/org/apache/cassandra/streaming/StreamResultFuture.java +++ b/src/java/org/apache/cassandra/streaming/StreamResultFuture.java @@ -36,6 +36,7 @@ import org.apache.cassandra.utils.FBUtilities; import static org.apache.cassandra.streaming.StreamingChannel.Factory.Global.streamingFactory; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * A future on the result ({@link StreamState}) of a streaming plan. @@ -198,7 +199,7 @@ public final class StreamResultFuture extends AsyncFuture void handleSessionComplete(StreamSession session) { - logger.info("[Stream #{}] Session with {} is {}", session.planId(), session.peer, session.state().name().toLowerCase()); + logger.info("[Stream #{}] Session with {} is {}", session.planId(), session.peer, toLowerCaseLocalized(session.state().name())); fireStreamEvent(new StreamEvent.SessionCompleteEvent(session)); SessionInfo sessionInfo = session.getSessionInfo(); coordinator.addSessionInfo(sessionInfo); diff --git a/src/java/org/apache/cassandra/streaming/StreamingState.java b/src/java/org/apache/cassandra/streaming/StreamingState.java index 3855960773..fbd66d1bb6 100644 --- a/src/java/org/apache/cassandra/streaming/StreamingState.java +++ b/src/java/org/apache/cassandra/streaming/StreamingState.java @@ -42,6 +42,7 @@ import org.apache.cassandra.utils.Clock; import org.apache.cassandra.utils.ObjectSizes; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID; public class StreamingState implements StreamEventHandler, IMeasurableMemory @@ -214,14 +215,14 @@ public class StreamingState implements StreamEventHandler, IMeasurableMemory { TableBuilder table = new TableBuilder(); table.add("id", id.toString()); - table.add("status", status().name().toLowerCase()); + table.add("status", toLowerCaseLocalized(status().name())); table.add("progress", (progress() * 100) + "%"); table.add("duration_ms", Long.toString(durationMillis())); table.add("last_updated_ms", Long.toString(lastUpdatedAtMillis())); table.add("failure_cause", failureCause()); table.add("success_message", successMessage()); for (Map.Entry e : stateTimesMillis().entrySet()) - table.add("status_" + e.getKey().name().toLowerCase() + "_ms", e.toString()); + table.add("status_" + toLowerCaseLocalized(e.getKey().name()) + "_ms", e.toString()); return table.toString(); } diff --git a/src/java/org/apache/cassandra/tcm/MetadataKeys.java b/src/java/org/apache/cassandra/tcm/MetadataKeys.java index 8028007815..bead377c0b 100644 --- a/src/java/org/apache/cassandra/tcm/MetadataKeys.java +++ b/src/java/org/apache/cassandra/tcm/MetadataKeys.java @@ -29,9 +29,11 @@ import com.google.common.collect.ImmutableSet; import org.apache.cassandra.tcm.extensions.ExtensionKey; import org.apache.cassandra.tcm.extensions.ExtensionValue; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class MetadataKeys { - public static final String CORE_NS = MetadataKeys.class.getPackage().getName().toLowerCase(Locale.ROOT); + public static final String CORE_NS = toLowerCaseLocalized(MetadataKeys.class.getPackage().getName(), Locale.ROOT); public static final MetadataKey SCHEMA = make(CORE_NS, "schema", "dist_schema"); public static final MetadataKey NODE_DIRECTORY = make(CORE_NS, "membership", "node_directory"); diff --git a/src/java/org/apache/cassandra/tools/RepairRunner.java b/src/java/org/apache/cassandra/tools/RepairRunner.java index cd09c57344..01aa520185 100644 --- a/src/java/org/apache/cassandra/tools/RepairRunner.java +++ b/src/java/org/apache/cassandra/tools/RepairRunner.java @@ -23,6 +23,7 @@ import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; +import org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus; import org.apache.cassandra.service.StorageServiceMBean; import org.apache.cassandra.utils.concurrent.Condition; @@ -32,10 +33,10 @@ import org.apache.cassandra.utils.progress.jmx.JMXNotificationProgressListener; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus; import static org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus.FAILED; import static org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus.valueOf; import static org.apache.cassandra.tools.NodeProbe.JMX_NOTIFICATION_POLL_INTERVAL_SECONDS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.apache.cassandra.utils.concurrent.Condition.newOneTimeCondition; import static org.apache.cassandra.utils.progress.ProgressEventType.*; @@ -165,7 +166,7 @@ public class RepairRunner extends JMXNotificationProgressListener case FAILED: printMessage(String.format("%s %s discovered repair %s.", triggeringCondition, - queriedString, parentRepairStatus.name().toLowerCase())); + queriedString, toLowerCaseLocalized(parentRepairStatus.name()))); if (parentRepairStatus == FAILED) { error = new IOException(messages.get(0)); diff --git a/src/java/org/apache/cassandra/tools/StandaloneScrubber.java b/src/java/org/apache/cassandra/tools/StandaloneScrubber.java index e7afc255c0..fe12e6d723 100644 --- a/src/java/org/apache/cassandra/tools/StandaloneScrubber.java +++ b/src/java/org/apache/cassandra/tools/StandaloneScrubber.java @@ -58,6 +58,8 @@ import org.apache.cassandra.utils.Pair; import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_UTIL_ALLOW_TOOL_REINIT_FOR_TEST; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public class StandaloneScrubber { @@ -241,12 +243,12 @@ public class StandaloneScrubber static HeaderFixMode fromCommandLine(String value) { - return valueOf(value.replace('-', '_').toUpperCase().trim()); + return valueOf(toUpperCaseLocalized(value.replace('-', '_')).trim()); } String asCommandLineOption() { - return name().toLowerCase().replace('_', '-'); + return toLowerCaseLocalized(name()).replace('_', '-'); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/ProfileLoad.java b/src/java/org/apache/cassandra/tools/nodetool/ProfileLoad.java index 45cade7560..01af271fcb 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/ProfileLoad.java +++ b/src/java/org/apache/cassandra/tools/nodetool/ProfileLoad.java @@ -41,6 +41,7 @@ import org.apache.cassandra.utils.Pair; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; import static org.apache.commons.lang3.StringUtils.join; @Command(name = "profileload", description = "Low footprint profiling of activity for a period of time") @@ -113,7 +114,7 @@ public class ProfileLoad extends NodeToolCmd Set available = Arrays.stream(SamplerType.values()).map(Enum::toString).collect(Collectors.toSet()); for (String s : samplers.split(",")) { - String sampler = s.trim().toUpperCase(); + String sampler = toUpperCaseLocalized(s.trim()); checkArgument(available.contains(sampler), String.format("'%s' sampler is not available from: %s", s, Arrays.toString(SamplerType.values()))); targets.add(sampler); } diff --git a/src/java/org/apache/cassandra/transport/CBUtil.java b/src/java/org/apache/cassandra/transport/CBUtil.java index d28d9c189e..eb0d5a16f6 100644 --- a/src/java/org/apache/cassandra/transport/CBUtil.java +++ b/src/java/org/apache/cassandra/transport/CBUtil.java @@ -47,6 +47,7 @@ import org.apache.cassandra.utils.UUIDGen; import org.apache.cassandra.utils.memory.MemoryUtil; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_NETTY_USE_HEAP_ALLOCATOR; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * ByteBuf utility methods. @@ -285,7 +286,7 @@ public abstract class CBUtil String value = CBUtil.readString(cb); try { - return Enum.valueOf(enumType, value.toUpperCase()); + return Enum.valueOf(enumType, toUpperCaseLocalized(value)); } catch (IllegalArgumentException e) { @@ -399,7 +400,7 @@ public abstract class CBUtil Map> m = new HashMap>(length); for (int i = 0; i < length; i++) { - String k = readString(cb).toUpperCase(); + String k = toUpperCaseLocalized(readString(cb)); List v = readStringList(cb); m.put(k, v); } diff --git a/src/java/org/apache/cassandra/transport/Client.java b/src/java/org/apache/cassandra/transport/Client.java index 45f5e1f2fa..96fea832a8 100644 --- a/src/java/org/apache/cassandra/transport/Client.java +++ b/src/java/org/apache/cassandra/transport/Client.java @@ -38,6 +38,9 @@ import org.apache.cassandra.utils.Hex; import org.apache.cassandra.utils.JVMStabilityInspector; import org.apache.cassandra.utils.MD5Digest; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class Client extends SimpleClient { private final SimpleEventHandler eventHandler = new SimpleEventHandler(); @@ -100,7 +103,7 @@ public class Client extends SimpleClient Iterator iter = splitter.split(line).iterator(); if (!iter.hasNext()) return null; - String msgType = iter.next().toUpperCase(); + String msgType = toUpperCaseLocalized(iter.next()); if (msgType.equals("STARTUP")) { Map options = new HashMap(); @@ -108,17 +111,17 @@ public class Client extends SimpleClient while (iter.hasNext()) { String next = iter.next(); - if (next.toLowerCase().equals("snappy")) + if (toLowerCaseLocalized(next).equals("snappy")) { options.put(StartupMessage.COMPRESSION, "snappy"); connection.setCompressor(Compressor.SnappyCompressor.instance); } - if (next.toLowerCase().equals("lz4")) + if (toLowerCaseLocalized(next).equals("lz4")) { options.put(StartupMessage.COMPRESSION, "lz4"); connection.setCompressor(Compressor.LZ4Compressor.instance); } - if (next.toLowerCase().equals("throw_on_overload")) + if (toLowerCaseLocalized(next).equals("throw_on_overload")) { options.put(StartupMessage.THROW_ON_OVERLOAD, "1"); connection.setThrowOnOverload(true); @@ -198,7 +201,7 @@ public class Client extends SimpleClient } else if (msgType.equals("REGISTER")) { - String type = line.substring(9).toUpperCase(); + String type = toUpperCaseLocalized(line.substring(9)); try { return new RegisterMessage(Collections.singletonList(Enum.valueOf(Event.Type.class, type))); diff --git a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java index 5ec3dc27ca..570b0975d6 100644 --- a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java @@ -29,6 +29,9 @@ import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.*; import org.apache.cassandra.utils.CassandraVersion; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + /** * The initial message of the protocol. * Sets up a number of connection options. @@ -89,7 +92,7 @@ public class StartupMessage extends Message.Request if (options.containsKey(COMPRESSION)) { - String compression = options.get(COMPRESSION).toLowerCase(); + String compression = toLowerCaseLocalized(options.get(COMPRESSION)); if (compression.equals("snappy")) { if (Compressor.SnappyCompressor.instance == null) @@ -158,7 +161,7 @@ public class StartupMessage extends Message.Request { Map newMap = new HashMap(options.size()); for (Map.Entry entry : options.entrySet()) - newMap.put(entry.getKey().toUpperCase(), entry.getValue()); + newMap.put(toUpperCaseLocalized(entry.getKey()), entry.getValue()); return newMap; } diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java index fd5c94c7dd..d52cfeb30b 100644 --- a/src/java/org/apache/cassandra/utils/FBUtilities.java +++ b/src/java/org/apache/cassandra/utils/FBUtilities.java @@ -103,6 +103,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.TRIGGERS_D import static org.apache.cassandra.config.CassandraRelevantProperties.USER_HOME; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public class FBUtilities { @@ -118,7 +119,7 @@ public class FBUtilities public static final BigInteger TWO = new BigInteger("2"); private static final String DEFAULT_TRIGGER_DIR = "triggers"; - private static final String OPERATING_SYSTEM = OS_NAME.getString().toLowerCase(); + private static final String OPERATING_SYSTEM = toLowerCaseLocalized(OS_NAME.getString()); public static final boolean isLinux = OPERATING_SYSTEM.contains("linux"); private static volatile InetAddress localInetAddress; @@ -1364,7 +1365,7 @@ public class FBUtilities public static String camelToSnake(String camel) { if (camel.chars().allMatch(Character::isUpperCase)) - return camel.toLowerCase(); + return toLowerCaseLocalized(camel); StringBuilder sb = new StringBuilder(); for (char c : camel.toCharArray()) @@ -1374,7 +1375,7 @@ public class FBUtilities // if first char is uppercase, then avoid adding the _ prefix if (sb.length() > 0) sb.append('_'); - sb.append(Character.toLowerCase(c)); + sb.append(Character.toLowerCase(c)); // checkstyle: permit this invocation } else { diff --git a/src/java/org/apache/cassandra/utils/GuidGenerator.java b/src/java/org/apache/cassandra/utils/GuidGenerator.java index e06270fa1d..1038f29c1a 100644 --- a/src/java/org/apache/cassandra/utils/GuidGenerator.java +++ b/src/java/org/apache/cassandra/utils/GuidGenerator.java @@ -23,6 +23,7 @@ import java.util.Random; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_SECURITY_EGD; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public class GuidGenerator { @@ -101,7 +102,7 @@ public class GuidGenerator private static String convertToStandardFormat(String valueAfterMD5) { - String raw = valueAfterMD5.toUpperCase(); + String raw = toUpperCaseLocalized(valueAfterMD5); StringBuilder sb = new StringBuilder(); sb.append(raw.substring(0, 8)) .append("-") diff --git a/src/java/org/apache/cassandra/utils/JsonUtils.java b/src/java/org/apache/cassandra/utils/JsonUtils.java index 1cdc13c55c..aa0963bf58 100644 --- a/src/java/org/apache/cassandra/utils/JsonUtils.java +++ b/src/java/org/apache/cassandra/utils/JsonUtils.java @@ -23,7 +23,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.Map; import com.fasterxml.jackson.core.JsonFactory; @@ -38,6 +37,7 @@ import org.apache.cassandra.io.util.FileOutputStreamPlus; import org.apache.cassandra.serializers.MarshalException; import static org.apache.cassandra.io.util.File.WriteMode.OVERWRITE; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public final class JsonUtils { @@ -203,7 +203,7 @@ public final class JsonUtils } // otherwise, lowercase it if needed - String lowered = mapKey.toLowerCase(Locale.US); + String lowered = toLowerCaseLocalized(mapKey); if (!mapKey.equals(lowered)) valueMap.put(lowered, valueMap.remove(mapKey)); } diff --git a/src/java/org/apache/cassandra/utils/LocalizeString.java b/src/java/org/apache/cassandra/utils/LocalizeString.java new file mode 100644 index 0000000000..d7d96cd7c9 --- /dev/null +++ b/src/java/org/apache/cassandra/utils/LocalizeString.java @@ -0,0 +1,60 @@ +/* + * 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.utils; + +import java.util.Locale; + +public class LocalizeString +{ + /** + * Convert the String to lower case, using {@link java.util.Locale#US} by default + */ + public static String toLowerCaseLocalized(String input) + { + return toLowerCaseLocalized(input, Locale.US); + } + + /** + * @param input The string to be converted to lower case. + * @param locale The locale to use for the conversion. + * @return String itself with lowercase and localized by your selection of {@link java.util.Locale}. + */ + public static String toLowerCaseLocalized(String input, Locale locale) + { + return input.toLowerCase(locale); // checkstyle: permit this invocation + } + + /** + * Convert the String to upper case, using {@link java.util.Locale#US} by default + */ + public static String toUpperCaseLocalized(String input) + { + return toUpperCaseLocalized(input, Locale.US); + } + + /** + * @param input The string to be converted to uppercase. + * @param locale The locale to use for the conversion. This parameter is optional. + * @return String itself with uppercase and localized by your selection of {@link java.util.Locale}. + */ + public static String toUpperCaseLocalized(String input, Locale locale) + { + return input.toUpperCase(locale); // checkstyle: permit this invocation + } +} \ No newline at end of file diff --git a/src/java/org/apache/cassandra/utils/NativeLibrary.java b/src/java/org/apache/cassandra/utils/NativeLibrary.java index 0f7172b5ae..84232dfabf 100644 --- a/src/java/org/apache/cassandra/utils/NativeLibrary.java +++ b/src/java/org/apache/cassandra/utils/NativeLibrary.java @@ -35,6 +35,7 @@ import org.apache.cassandra.io.FSWriteError; import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_MISSING_NATIVE_FILE_HINTS; import static org.apache.cassandra.config.CassandraRelevantProperties.OS_ARCH; import static org.apache.cassandra.config.CassandraRelevantProperties.OS_NAME; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.apache.cassandra.utils.NativeLibrary.OSType.LINUX; import static org.apache.cassandra.utils.NativeLibrary.OSType.MAC; import static org.apache.cassandra.utils.NativeLibrary.OSType.AIX; @@ -102,7 +103,7 @@ public final class NativeLibrary default: wrappedLibrary = new NativeLibraryLinux(); } - if (OS_ARCH.getString().toLowerCase().contains("ppc")) + if (toLowerCaseLocalized(OS_ARCH.getString()).contains("ppc")) { if (osType == LINUX) { @@ -134,7 +135,7 @@ public final class NativeLibrary */ private static OSType getOsType() { - String osName = OS_NAME.getString().toLowerCase(); + String osName = toLowerCaseLocalized(OS_NAME.getString()); if (osName.contains("linux")) return LINUX; else if (osName.contains("mac")) diff --git a/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java b/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java index 19dcc23dcf..6ce840efbb 100644 --- a/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java +++ b/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java @@ -35,6 +35,8 @@ import org.apache.cassandra.dht.Token.TokenFactory; import org.apache.cassandra.io.sstable.SSTableLoader; import org.apache.cassandra.schema.TableMetadata; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class NativeSSTableLoaderClient extends SSTableLoader.Client { protected final Map tables; @@ -203,7 +205,7 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client private static ColumnMetadata createDefinitionFromRow(Row row, String keyspace, String table, Types types) { - ClusteringOrder order = ClusteringOrder.valueOf(row.getString("clustering_order").toUpperCase()); + ClusteringOrder order = ClusteringOrder.valueOf(toUpperCaseLocalized(row.getString("clustering_order"))); AbstractType type = CQLTypeParser.parse(keyspace, row.getString("type"), types); if (order == ClusteringOrder.DESC) type = ReversedType.getInstance(type); @@ -211,7 +213,7 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client ColumnIdentifier name = new ColumnIdentifier(row.getBytes("column_name_bytes"), row.getString("column_name")); int position = row.getInt("position"); - org.apache.cassandra.schema.ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(row.getString("kind").toUpperCase()); + org.apache.cassandra.schema.ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(toUpperCaseLocalized(row.getString("kind"))); return new ColumnMetadata(keyspace, table, name, type, position, kind, null); } @@ -219,7 +221,7 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client { String name = row.getString("column_name"); AbstractType type = CQLTypeParser.parse(keyspace, row.getString("type"), Types.none()); - ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(row.getString("kind").toUpperCase()); + ColumnMetadata.Kind kind = ColumnMetadata.Kind.valueOf(toUpperCaseLocalized(row.getString("kind"))); ColumnMetadata column = new ColumnMetadata(keyspace, table, ColumnIdentifier.getInterned(name, true), type, ColumnMetadata.NO_POSITION, kind, null); long droppedTime = row.getTimestamp("dropped_time").getTime(); return new DroppedColumn(column, droppedTime); diff --git a/src/java/org/apache/cassandra/utils/binlog/BinLog.java b/src/java/org/apache/cassandra/utils/binlog/BinLog.java index 8b0e025700..313d6b4549 100644 --- a/src/java/org/apache/cassandra/utils/binlog/BinLog.java +++ b/src/java/org/apache/cassandra/utils/binlog/BinLog.java @@ -54,6 +54,7 @@ import org.apache.cassandra.utils.concurrent.WeightedQueue; import static java.lang.String.format; import static org.apache.cassandra.config.CassandraRelevantProperties.CHRONICLE_ANNOUNCER_DISABLE; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; /** * Bin log is a is quick and dirty binary log that is kind of a NIH version of binary logging with a traditional logging @@ -389,7 +390,7 @@ public class BinLog implements Runnable public Builder rollCycle(String rollCycle) { Preconditions.checkNotNull(rollCycle, "rollCycle was null"); - rollCycle = rollCycle.toUpperCase(); + rollCycle = toUpperCaseLocalized(rollCycle); Preconditions.checkNotNull(RollCycles.valueOf(rollCycle), "unrecognized roll cycle"); this.rollCycle = rollCycle; return this; diff --git a/test/distributed/org/apache/cassandra/distributed/Cluster.java b/test/distributed/org/apache/cassandra/distributed/Cluster.java index 788171dd9e..4effc4e9c4 100644 --- a/test/distributed/org/apache/cassandra/distributed/Cluster.java +++ b/test/distributed/org/apache/cassandra/distributed/Cluster.java @@ -29,6 +29,8 @@ import org.apache.cassandra.distributed.impl.Instance; import org.apache.cassandra.distributed.shared.Versions; import org.apache.cassandra.net.Message; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * A simple cluster supporting only the 'current' Cassandra version, offering easy access to the convenience methods * of IInvokableInstance on each node. @@ -81,7 +83,7 @@ public class Cluster extends AbstractCluster { get(1).acceptsOnInstance((IIsolatedExecutor.SerializableConsumer) (msgPassed) -> { Message decoded = Instance.deserializeMessage(msgPassed); - if (!decoded.verb().toString().toLowerCase().contains("gossip")) + if (!toLowerCaseLocalized(decoded.verb().toString()).contains("gossip")) System.out.println(String.format("MSG %d -> %d: %s | %s", from, to, decoded, decoded.payload)); }).accept(msg); } diff --git a/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java b/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java index 405279aae6..5727a020b6 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/FailingRepairTest.java @@ -76,6 +76,8 @@ import org.apache.cassandra.service.ActiveRepairService.ParentRepairStatus; import org.apache.cassandra.service.StorageService; import org.awaitility.Awaitility; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + @RunWith(Parameterized.class) public class FailingRepairTest extends TestBaseImpl implements Serializable { @@ -132,7 +134,7 @@ public class FailingRepairTest extends TestBaseImpl implements Serializable private static String getCfName(Verb type, RepairParallelism parallelism, boolean withTracing) { - return type.name().toLowerCase() + "_" + parallelism.name().toLowerCase() + "_" + withTracing; + return toLowerCaseLocalized(type.name()) + "_" + toLowerCaseLocalized(parallelism.name()) + "_" + withTracing; } @BeforeClass diff --git a/test/distributed/org/apache/cassandra/distributed/test/ReadDigestConsistencyTest.java b/test/distributed/org/apache/cassandra/distributed/test/ReadDigestConsistencyTest.java index 85c2783161..907ce0df04 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/ReadDigestConsistencyTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/ReadDigestConsistencyTest.java @@ -33,6 +33,8 @@ import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.Throwables; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class ReadDigestConsistencyTest extends TestBaseImpl { private final static Logger logger = LoggerFactory.getLogger(ReadDigestConsistencyTest.class); @@ -101,7 +103,7 @@ public class ReadDigestConsistencyTest extends TestBaseImpl Arrays.toString(boundValues), coordinator.instance().broadcastAddress(), coordinator.instance().getReleaseVersionString()), - activity.toLowerCase().contains("mismatch for key")); + toLowerCaseLocalized(activity).contains("mismatch for key")); } } diff --git a/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorBase.java b/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorBase.java index 0fc2554b01..6967b9f119 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorBase.java +++ b/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorBase.java @@ -35,6 +35,7 @@ import org.apache.cassandra.distributed.test.DistributedRepairUtils.RepairParall import org.apache.cassandra.distributed.test.DistributedRepairUtils.RepairType; import static org.apache.cassandra.config.CassandraRelevantProperties.NODETOOL_JMX_NOTIFICATION_POLL_INTERVAL_SECONDS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public class RepairCoordinatorBase extends TestBaseImpl { @@ -98,7 +99,7 @@ public class RepairCoordinatorBase extends TestBaseImpl protected String postfix() { - return repairType.name().toLowerCase() + "_" + parallelism.name().toLowerCase() + "_" + withNotifications; + return toLowerCaseLocalized(repairType.name()) + "_" + toLowerCaseLocalized(parallelism.name()) + "_" + withNotifications; } protected NodeToolResult repair(int node, String... args) { diff --git a/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorFailingMessageTest.java b/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorFailingMessageTest.java index 0d046497b9..dbd2680ad9 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorFailingMessageTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/RepairCoordinatorFailingMessageTest.java @@ -42,6 +42,7 @@ import org.apache.cassandra.net.Verb; import static java.lang.String.format; import static org.apache.cassandra.distributed.api.IMessageFilters.Matcher.of; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; @RunWith(Parameterized.class) @Ignore("Until CASSANDRA-15566 is in these tests all time out") @@ -100,7 +101,7 @@ public class RepairCoordinatorFailingMessageTest extends TestBaseImpl implements private String postfix() { - return repairType.name().toLowerCase(); + return toLowerCaseLocalized(repairType.name()); } private NodeToolResult repair(int node, String... args) { diff --git a/test/distributed/org/apache/cassandra/distributed/test/SSTableIdGenerationTest.java b/test/distributed/org/apache/cassandra/distributed/test/SSTableIdGenerationTest.java index 9514faf9ea..a44532ee15 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/SSTableIdGenerationTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/SSTableIdGenerationTest.java @@ -67,6 +67,7 @@ import static org.apache.cassandra.db.SystemKeyspace.LEGACY_SSTABLE_ACTIVITY; import static org.apache.cassandra.db.SystemKeyspace.SSTABLE_ACTIVITY_V2; import static org.apache.cassandra.distributed.shared.FutureUtils.waitOn; import static org.apache.cassandra.distributed.test.ExecUtil.rethrow; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.assertj.core.api.Assertions.assertThat; public class SSTableIdGenerationTest extends TestBaseImpl @@ -176,7 +177,7 @@ public class SSTableIdGenerationTest extends TestBaseImpl // create a table and two sstables with sequential id for each strategy, the sstables will contain overlapping partitions for (Class compactionStrategyClass : compactionStrategyClasses) { - String tableName = "tbl_" + compactionStrategyClass.getSimpleName().toLowerCase(); + String tableName = "tbl_" + toLowerCaseLocalized(compactionStrategyClass.getSimpleName()); cluster.schemaChange(createTableStmt(KEYSPACE, tableName, compactionStrategyClass)); createSSTables(cluster.get(1), KEYSPACE, tableName, 1, 2); @@ -189,7 +190,7 @@ public class SSTableIdGenerationTest extends TestBaseImpl // create another two sstables with uuid for each previously created table for (Class compactionStrategyClass : compactionStrategyClasses) { - String tableName = "tbl_" + compactionStrategyClass.getSimpleName().toLowerCase(); + String tableName = "tbl_" + toLowerCaseLocalized(compactionStrategyClass.getSimpleName()); createSSTables(cluster.get(1), KEYSPACE, tableName, 3, 4); diff --git a/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java b/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java index e2a4edeca5..c800963c01 100644 --- a/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java +++ b/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java @@ -78,6 +78,8 @@ import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.ObjectSizes; import org.apache.cassandra.utils.concurrent.Refs; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class CompactionAllocationTest { private static final Logger logger = LoggerFactory.getLogger(CompactionAllocationTest.class); @@ -494,7 +496,7 @@ public class CompactionAllocationTest private static void testTinyPartitions(String name, int numSSTable, int sstablePartitions, boolean overlap) throws Throwable { - String ksname = "ks_" + name.toLowerCase(); + String ksname = "ks_" + toLowerCaseLocalized(name); SchemaLoader.createKeyspace(ksname, KeyspaceParams.simple(1), CreateTableStatement.parse("CREATE TABLE tbl (k INT PRIMARY KEY, v INT)", ksname).build()); @@ -603,7 +605,7 @@ public class CompactionAllocationTest private static void testMediumPartitions(String name, int numSSTable, int sstablePartitions, boolean overlap, boolean overlapCK) throws Throwable { - String ksname = "ks_" + name.toLowerCase(); + String ksname = "ks_" + toLowerCaseLocalized(name); SchemaLoader.createKeyspace(ksname, KeyspaceParams.simple(1), CreateTableStatement.parse("CREATE TABLE tbl (k text, c text, v1 text, v2 text, v3 text, v4 text, PRIMARY KEY (k, c))", ksname).build()); @@ -702,7 +704,7 @@ public class CompactionAllocationTest private static void testWidePartitions(String name, int numSSTable, int sstablePartitions, boolean overlap, boolean overlapCK) throws Throwable { - String ksname = "ks_" + name.toLowerCase(); + String ksname = "ks_" + toLowerCaseLocalized(name); SchemaLoader.createKeyspace(ksname, KeyspaceParams.simple(1), CreateTableStatement.parse("CREATE TABLE tbl (k text, c text, v1 text, v2 text, v3 text, v4 text, PRIMARY KEY (k, c))", ksname).build()); @@ -806,7 +808,7 @@ public class CompactionAllocationTest int sstablePartitions, IndexDef...indexes) throws Throwable { - String ksname = "ks_" + name.toLowerCase(); + String ksname = "ks_" + toLowerCaseLocalized(name); SchemaLoader.createKeyspace(ksname, KeyspaceParams.simple(1), CreateTableStatement.parse("CREATE TABLE tbl (k text, c text, v1 text, v2 text, v3 text, v4 text, PRIMARY KEY (k, c))", ksname).build()); diff --git a/test/simulator/main/org/apache/cassandra/simulator/Action.java b/test/simulator/main/org/apache/cassandra/simulator/Action.java index edb661fae1..76c22cef4b 100644 --- a/test/simulator/main/org/apache/cassandra/simulator/Action.java +++ b/test/simulator/main/org/apache/cassandra/simulator/Action.java @@ -897,7 +897,7 @@ public abstract class Action implements PriorityQueueNode continue; if (!transitive.is(modifier)) builder.append(modifier.displayId); - else builder.append(Character.toUpperCase(modifier.displayId)); + else builder.append(Character.toUpperCase(modifier.displayId)); // checkstyle: permit this invocation } boolean hasTransitiveOnly = false; diff --git a/test/simulator/main/org/apache/cassandra/simulator/SimulationRunner.java b/test/simulator/main/org/apache/cassandra/simulator/SimulationRunner.java index 5542d0d1e2..deaa462df3 100644 --- a/test/simulator/main/org/apache/cassandra/simulator/SimulationRunner.java +++ b/test/simulator/main/org/apache/cassandra/simulator/SimulationRunner.java @@ -81,6 +81,7 @@ import static org.apache.cassandra.simulator.debug.Record.record; import static org.apache.cassandra.simulator.debug.SelfReconcile.reconcileWithSelf; import static org.apache.cassandra.simulator.utils.IntRange.parseRange; import static org.apache.cassandra.simulator.utils.LongRange.parseNanosRange; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; @SuppressWarnings({ "ZeroLengthArrayAllocation", "CodeBlock2Expr", "SameParameterValue", "DynamicRegexReplaceableByCompiledPattern", "CallToSystemGC" }) public class SimulationRunner @@ -281,7 +282,7 @@ public class SimulationRunner Optional.ofNullable(topologyChanges).ifPresent(topologyChanges -> { builder.topologyChanges(stream(topologyChanges.split(",")) .filter(v -> !v.isEmpty()) - .map(v -> TopologyChange.valueOf(v.toUpperCase())) + .map(v -> TopologyChange.valueOf(toUpperCaseLocalized(v))) .toArray(TopologyChange[]::new)); }); parseNanosRange(Optional.ofNullable(topologyChangeInterval)).ifPresent(builder::topologyChangeIntervalNanos); @@ -289,7 +290,7 @@ public class SimulationRunner Optional.ofNullable(priority).ifPresent(kinds -> { builder.scheduler(stream(kinds.split(",")) .filter(v -> !v.isEmpty()) - .map(v -> RunnableActionScheduler.Kind.valueOf(v.toUpperCase())) + .map(v -> RunnableActionScheduler.Kind.valueOf(toUpperCaseLocalized(v))) .toArray(RunnableActionScheduler.Kind[]::new)); }); diff --git a/test/unit/org/apache/cassandra/SchemaLoader.java b/test/unit/org/apache/cassandra/SchemaLoader.java index d18dd0aa96..73ef7285b3 100644 --- a/test/unit/org/apache/cassandra/SchemaLoader.java +++ b/test/unit/org/apache/cassandra/SchemaLoader.java @@ -52,6 +52,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.ALLOW_UNSA import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_COMPRESSION; import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_COMPRESSION_ALGO; import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public class SchemaLoader { @@ -745,7 +746,7 @@ public static TableMetadata.Builder clusteringSASICFMD(String ksName, String cfN private static CompressionParams compressionParams(int chunkLength) { - String algo = TEST_COMPRESSION_ALGO.getString().toLowerCase(); + String algo = toLowerCaseLocalized(TEST_COMPRESSION_ALGO.getString()); switch (algo) { case "deflate": diff --git a/test/unit/org/apache/cassandra/auth/CassandraNetworkAuthorizerTest.java b/test/unit/org/apache/cassandra/auth/CassandraNetworkAuthorizerTest.java index b255ad59ff..6ec69d5c85 100644 --- a/test/unit/org/apache/cassandra/auth/CassandraNetworkAuthorizerTest.java +++ b/test/unit/org/apache/cassandra/auth/CassandraNetworkAuthorizerTest.java @@ -41,6 +41,7 @@ import static org.apache.cassandra.auth.AuthKeyspace.NETWORK_PERMISSIONS; import static org.apache.cassandra.auth.AuthTestUtils.auth; import static org.apache.cassandra.auth.AuthTestUtils.getRolesReadCount; import static org.apache.cassandra.schema.SchemaConstants.AUTH_KEYSPACE_NAME; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -100,7 +101,7 @@ public class CassandraNetworkAuthorizerTest extends CQLTester private static String createName() { - return RandomStringUtils.randomAlphabetic(8).toLowerCase(); + return toLowerCaseLocalized(RandomStringUtils.randomAlphabetic(8)); } private static DCPermissions dcPerms(String username) diff --git a/test/unit/org/apache/cassandra/config/DataStorageSpecTest.java b/test/unit/org/apache/cassandra/config/DataStorageSpecTest.java index 334e33f259..ff89693d5c 100644 --- a/test/unit/org/apache/cassandra/config/DataStorageSpecTest.java +++ b/test/unit/org/apache/cassandra/config/DataStorageSpecTest.java @@ -28,6 +28,7 @@ import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.BYTES; 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; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.*; import static org.quicktheories.QuickTheory.qt; @@ -242,7 +243,7 @@ public class DataStorageSpecTest { qt().forAll(gen()).check(there -> { DataStorageSpec.LongBytesBound back = new DataStorageSpec.LongBytesBound(there.toString()); - DataStorageSpec.LongBytesBound BACK = new DataStorageSpec.LongBytesBound(there.toString().toUpperCase(Locale.ROOT).replace("I", "i")); + DataStorageSpec.LongBytesBound BACK = new DataStorageSpec.LongBytesBound(toUpperCaseLocalized(there.toString(), Locale.ROOT).replace("I", "i")); return there.equals(back) && there.equals(BACK); }); } diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java index 27d4d19528..dea0d867ee 100644 --- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java +++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java @@ -282,6 +282,7 @@ public class DatabaseDescriptorRefTest "org.apache.cassandra.utils.CloseableIterator", "org.apache.cassandra.utils.FBUtilities", "org.apache.cassandra.utils.FBUtilities$1", + "org.apache.cassandra.utils.LocalizeString", "org.apache.cassandra.utils.SystemInfo", "org.apache.cassandra.utils.Pair", "org.apache.cassandra.utils.binlog.BinLogOptions", diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index 624b069e9c..54171f9a08 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -39,7 +39,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -204,6 +203,7 @@ import static org.apache.cassandra.cql3.SchemaElement.SchemaElementType.TABLE; import static org.apache.cassandra.cql3.SchemaElement.SchemaElementType.TYPE; import static org.apache.cassandra.metrics.CassandraMetricsRegistry.createMetricsKeyspaceTables; import static org.apache.cassandra.schema.SchemaConstants.VIRTUAL_METRICS; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -1046,7 +1046,7 @@ public abstract class CQLTester private String createSchemaElementName(SchemaElement.SchemaElementType type, String keyspace) { String prefix = keyspace == null ? "" : keyspace + '.'; - String typeName = type == MATERIALIZED_VIEW ? "mv" : type.name().toLowerCase(Locale.US); + String typeName = type == MATERIALIZED_VIEW ? "mv" : toLowerCaseLocalized(type.name()); int sequence = seqNumber.getAndIncrement(); int usedSpaceSoFar = prefix.length() + typeName.length() + Math.max(2, numberOfDigits(sequence)) + 1; String testMethodName = StringUtils.truncate(getTestMethodName(), SchemaConstants.NAME_LENGTH - usedSpaceSoFar); @@ -1329,7 +1329,7 @@ public abstract class CQLTester index = ParseUtils.isQuoted(index, '\"') ? ParseUtils.unDoubleQuote(index) - : index.toLowerCase(); + : toLowerCaseLocalized(index); return Pair.create(keyspace, index); } @@ -2738,7 +2738,7 @@ public abstract class CQLTester private String getTestMethodName() { - return decorateCQLWithTestNames && testName.getMethodName() != null ? '_' + testName.getMethodName().toLowerCase().replaceAll("[^\\w]", "_") + return decorateCQLWithTestNames && testName.getMethodName() != null ? '_' + toLowerCaseLocalized(testName.getMethodName()).replaceAll("[^\\w]", "_") : ""; } diff --git a/test/unit/org/apache/cassandra/cql3/KeywordTestBase.java b/test/unit/org/apache/cassandra/cql3/KeywordTestBase.java index aa6e508fa4..274041e27c 100644 --- a/test/unit/org/apache/cassandra/cql3/KeywordTestBase.java +++ b/test/unit/org/apache/cassandra/cql3/KeywordTestBase.java @@ -31,6 +31,8 @@ import org.junit.Test; import org.apache.cassandra.exceptions.SyntaxException; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * This class tests all keywords which took a long time. Hence it was split into multiple * KeywordTestSplitN to prevent CI timing out. If timeouts reappear split it further @@ -105,7 +107,7 @@ public abstract class KeywordTestBase extends CQLTester logger.info(selectStatement); rs = execute(selectStatement); row = rs.one(); - String value = row.getString(keyword.toLowerCase()); + String value = row.getString(toLowerCaseLocalized(keyword)); Assert.assertEquals(keyword, value); /* Make a materialized view using the fields (cannot re-use the name as MV must be in same keyspace). diff --git a/test/unit/org/apache/cassandra/cql3/functions/NativeFunctionsTest.java b/test/unit/org/apache/cassandra/cql3/functions/NativeFunctionsTest.java index be55d17038..4ecfc7d99b 100644 --- a/test/unit/org/apache/cassandra/cql3/functions/NativeFunctionsTest.java +++ b/test/unit/org/apache/cassandra/cql3/functions/NativeFunctionsTest.java @@ -29,6 +29,8 @@ import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.schema.UserFunctions; import org.assertj.core.api.Assertions; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class NativeFunctionsTest { /** @@ -154,7 +156,7 @@ public class NativeFunctionsTest Assertions.assertThat(function.argTypes()).isEqualTo(newFunction.argTypes()); Assertions.assertThat(function.returnType()).isEqualTo(newFunction.returnType()); Assertions.assertThat(function.getClass()).isEqualTo(newFunction.getClass()); - Assertions.assertThat(function.name().name.toLowerCase()) + Assertions.assertThat(toLowerCaseLocalized(function.name().name)) .isEqualTo(StringUtils.remove(newFunction.name().name, '_')); } } @@ -190,7 +192,7 @@ public class NativeFunctionsTest Assertions.assertThat(factory.name).isNotEqualTo(newFactory.name); Assertions.assertThat(factory.parameters).isEqualTo(newFactory.parameters); Assertions.assertThat(factory.getClass()).isEqualTo(newFactory.getClass()); - Assertions.assertThat(factory.name().name.toLowerCase()) + Assertions.assertThat(toLowerCaseLocalized(factory.name().name)) .isEqualTo(StringUtils.remove(newFactory.name().name, '_')); } } @@ -198,7 +200,7 @@ public class NativeFunctionsTest private static boolean satisfiesConventions(FunctionName functionName) { String name = functionName.name; - return name.equals(name.toLowerCase()) && + return name.equals(toLowerCaseLocalized(name)) && !LEGACY_FUNCTION_NAMES.containsKey(name); } } diff --git a/test/unit/org/apache/cassandra/cql3/functions/masking/PartialMaskingFunctionTest.java b/test/unit/org/apache/cassandra/cql3/functions/masking/PartialMaskingFunctionTest.java index 89d20d0d58..3a1d455169 100644 --- a/test/unit/org/apache/cassandra/cql3/functions/masking/PartialMaskingFunctionTest.java +++ b/test/unit/org/apache/cassandra/cql3/functions/masking/PartialMaskingFunctionTest.java @@ -31,6 +31,7 @@ import org.apache.cassandra.schema.SchemaConstants; import org.assertj.core.api.Assertions; import static java.lang.String.format; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; /** * Tests for {@link PartialMaskingFunction}. @@ -46,7 +47,7 @@ public class PartialMaskingFunctionTest extends MaskingFunctionTester protected void testMaskingOnColumn(PartialMaskingFunction.Kind masker, String name, CQL3Type type, Object value) throws Throwable { - String functionName = SchemaConstants.SYSTEM_KEYSPACE_NAME + ".mask_" + masker.name().toLowerCase(); + String functionName = SchemaConstants.SYSTEM_KEYSPACE_NAME + ".mask_" + toLowerCaseLocalized(masker.name()); if (type.getType() instanceof StringType) { diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java index 2d2a626e97..c1365e4cc3 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java @@ -19,7 +19,6 @@ package org.apache.cassandra.cql3.validation.entities; import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; @@ -64,6 +63,7 @@ import static org.apache.cassandra.Util.throwAssert; import static org.apache.cassandra.utils.ByteBufferUtil.EMPTY_BYTE_BUFFER; import static org.apache.cassandra.utils.ByteBufferUtil.bytes; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -113,7 +113,7 @@ public class SecondaryIndexTest extends CQLTester { assertInvalidMessage(format("Index '%s.%s' doesn't exist", KEYSPACE, - removeQuotes(indexName.toLowerCase(Locale.US))), + removeQuotes(toLowerCaseLocalized(indexName))), format("DROP INDEX %s.%s", KEYSPACE, indexName)); createTable("CREATE TABLE %s (a int primary key, b int);"); @@ -121,7 +121,7 @@ public class SecondaryIndexTest extends CQLTester createIndexAsync("CREATE INDEX IF NOT EXISTS " + indexName + " ON %s(b);"); assertInvalidMessage(format("Index '%s' already exists", - removeQuotes(indexName.toLowerCase(Locale.US))), + removeQuotes(toLowerCaseLocalized(indexName))), "CREATE INDEX " + indexName + " ON %s(b)"); // IF NOT EXISTS should apply in cases where the new index differs from an existing one in name only @@ -130,8 +130,8 @@ public class SecondaryIndexTest extends CQLTester createIndexAsync("CREATE INDEX IF NOT EXISTS " + otherIndexName + " ON %s(b)"); assertEquals(1, getCurrentColumnFamilyStore().metadata().indexes.size()); assertInvalidMessage(format("Index %s is a duplicate of existing index %s", - removeQuotes(otherIndexName.toLowerCase(Locale.US)), - removeQuotes(indexName.toLowerCase(Locale.US))), + removeQuotes(toLowerCaseLocalized(otherIndexName)), + removeQuotes(toLowerCaseLocalized(indexName))), "CREATE INDEX " + otherIndexName + " ON %s(b)"); execute("INSERT INTO %s (a, b) values (?, ?);", 0, 0); @@ -156,7 +156,7 @@ public class SecondaryIndexTest extends CQLTester dropIndex(format("DROP INDEX IF EXISTS %s.%s", KEYSPACE, indexName)); assertInvalidMessage(format("Index '%s.%s' doesn't exist", KEYSPACE, - removeQuotes(indexName.toLowerCase(Locale.US))), + removeQuotes(toLowerCaseLocalized(indexName))), format("DROP INDEX %s.%s", KEYSPACE, indexName)); } diff --git a/test/unit/org/apache/cassandra/db/compaction/unified/ControllerTest.java b/test/unit/org/apache/cassandra/db/compaction/unified/ControllerTest.java index 162e7fc8a5..7b8f0477e7 100644 --- a/test/unit/org/apache/cassandra/db/compaction/unified/ControllerTest.java +++ b/test/unit/org/apache/cassandra/db/compaction/unified/ControllerTest.java @@ -45,6 +45,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import static java.lang.String.format; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -142,7 +143,7 @@ public class ControllerTest options.putIfAbsent(Controller.TARGET_SSTABLE_SIZE_OPTION, FBUtilities.prettyPrintMemory(100 << 20)); // The below value is based on the value in the above statement. Decreasing the above statement should result in a decrease below. options.putIfAbsent(Controller.MIN_SSTABLE_SIZE_OPTION, "70.710MiB"); - options.putIfAbsent(Controller.OVERLAP_INCLUSION_METHOD_OPTION, Overlaps.InclusionMethod.SINGLE.toString().toLowerCase()); + options.putIfAbsent(Controller.OVERLAP_INCLUSION_METHOD_OPTION, toLowerCaseLocalized(Overlaps.InclusionMethod.SINGLE.toString())); options.putIfAbsent(Controller.SSTABLE_GROWTH_OPTION, "0.5"); } diff --git a/test/unit/org/apache/cassandra/db/guardrails/GuardrailPasswordTest.java b/test/unit/org/apache/cassandra/db/guardrails/GuardrailPasswordTest.java index d06a1696bb..774868079d 100644 --- a/test/unit/org/apache/cassandra/db/guardrails/GuardrailPasswordTest.java +++ b/test/unit/org/apache/cassandra/db/guardrails/GuardrailPasswordTest.java @@ -36,6 +36,7 @@ import static java.lang.String.format; import static java.util.Collections.singletonList; import static org.apache.cassandra.db.guardrails.CassandraPasswordConfiguration.LENGTH_FAIL_KEY; import static org.apache.cassandra.db.guardrails.CassandraPasswordConfiguration.LENGTH_WARN_KEY; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -121,7 +122,7 @@ public class GuardrailPasswordTest extends GuardrailTester private String getEntityName(String name) { - return (name + entity).toLowerCase(); + return toLowerCaseLocalized(name + entity); } private void testPasswordGuardrailInternal() throws Throwable diff --git a/test/unit/org/apache/cassandra/db/tries/TrieToDotTest.java b/test/unit/org/apache/cassandra/db/tries/TrieToDotTest.java index b4955dbc08..92d59269d6 100644 --- a/test/unit/org/apache/cassandra/db/tries/TrieToDotTest.java +++ b/test/unit/org/apache/cassandra/db/tries/TrieToDotTest.java @@ -22,6 +22,8 @@ import org.junit.Test; import org.apache.cassandra.io.compress.BufferType; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class TrieToDotTest { @Test @@ -30,7 +32,7 @@ public class TrieToDotTest InMemoryTrie trie = new InMemoryTrie<>(BufferType.OFF_HEAP); String s = "Trie node types and manipulation mechanisms. The main purpose of this is to allow for handling tries directly as" + " they are on disk without any serialization, and to enable the creation of such files."; - s = s.toLowerCase(); + s = toLowerCaseLocalized(s); for (String word : s.split("[^a-z]+")) trie.putRecursive(InMemoryTrieTestBase.comparable(word), word, (x, y) -> y); diff --git a/test/unit/org/apache/cassandra/db/tries/TrieToMermaidTest.java b/test/unit/org/apache/cassandra/db/tries/TrieToMermaidTest.java index 61b5f4f893..ed1afa462e 100644 --- a/test/unit/org/apache/cassandra/db/tries/TrieToMermaidTest.java +++ b/test/unit/org/apache/cassandra/db/tries/TrieToMermaidTest.java @@ -22,6 +22,8 @@ import org.junit.Test; import org.apache.cassandra.io.compress.BufferType; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class TrieToMermaidTest { @Test @@ -30,7 +32,7 @@ public class TrieToMermaidTest InMemoryTrie trie = new InMemoryTrie<>(BufferType.OFF_HEAP); // This was used as a basis the graphs in BTIFormat.md String s = "a allow an and any are as node of on the this to trie types with without"; - s = s.toLowerCase(); + s = toLowerCaseLocalized(s); for (String word : s.split("[^a-z]+")) trie.putRecursive(InMemoryTrieTestBase.comparable(word), word, (x, y) -> y); diff --git a/test/unit/org/apache/cassandra/db/virtual/LocalRepairTablesTest.java b/test/unit/org/apache/cassandra/db/virtual/LocalRepairTablesTest.java index 97dea78484..96f09400ec 100644 --- a/test/unit/org/apache/cassandra/db/virtual/LocalRepairTablesTest.java +++ b/test/unit/org/apache/cassandra/db/virtual/LocalRepairTablesTest.java @@ -56,6 +56,8 @@ import org.apache.cassandra.utils.Clock; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class LocalRepairTablesTest extends CQLTester { private static final String KS_NAME = "vts"; @@ -245,7 +247,7 @@ public class LocalRepairTablesTest extends CQLTester private > void assertState(String table, State state, T expectedState) throws Throwable { assertRowsIgnoringOrder(execute(t("SELECT id, completed, status, failure_cause, success_message FROM %s." + table + " WHERE id = ?"), state.getId()), - row(state.getId(), false, expectedState.name().toLowerCase(), null, null)); + row(state.getId(), false, toLowerCaseLocalized(expectedState.name()), null, null)); } private void assertSuccess(String table, State state) throws Throwable diff --git a/test/unit/org/apache/cassandra/db/virtual/SSTableTasksTableTest.java b/test/unit/org/apache/cassandra/db/virtual/SSTableTasksTableTest.java index e6de58d37a..5d387f1d9e 100644 --- a/test/unit/org/apache/cassandra/db/virtual/SSTableTasksTableTest.java +++ b/test/unit/org/apache/cassandra/db/virtual/SSTableTasksTableTest.java @@ -37,6 +37,7 @@ import org.apache.cassandra.io.sstable.format.SSTableReader; import org.apache.cassandra.schema.MockSchema; import org.apache.cassandra.utils.TimeUUID; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID; public class SSTableTasksTableTest extends CQLTester @@ -91,7 +92,7 @@ public class SSTableTasksTableTest extends CQLTester CompactionManager.instance.active.beginCompaction(compactionHolder); UntypedResultSet result = execute("SELECT * FROM vts.sstable_tasks"); assertRows(result, row(CQLTester.KEYSPACE, currentTable(), compactionId, 1.0 * bytesCompacted / bytesTotal, - OperationType.COMPACTION.toString().toLowerCase(), bytesCompacted, sstables.size(), + toLowerCaseLocalized(OperationType.COMPACTION.toString()), bytesCompacted, sstables.size(), directory, bytesTotal, CompactionInfo.Unit.BYTES.toString())); CompactionManager.instance.active.finishCompaction(compactionHolder); diff --git a/test/unit/org/apache/cassandra/db/virtual/StreamingVirtualTableTest.java b/test/unit/org/apache/cassandra/db/virtual/StreamingVirtualTableTest.java index 07f2815c86..30a70338f9 100644 --- a/test/unit/org/apache/cassandra/db/virtual/StreamingVirtualTableTest.java +++ b/test/unit/org/apache/cassandra/db/virtual/StreamingVirtualTableTest.java @@ -54,6 +54,7 @@ import org.apache.cassandra.streaming.StreamingState; import org.apache.cassandra.utils.FBUtilities; import org.assertj.core.util.Throwables; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID; public class StreamingVirtualTableTest extends CQLTester @@ -185,7 +186,7 @@ public class StreamingVirtualTableTest extends CQLTester long fileSize = summary.totalSize / summary.files; for (int i = 0; i < summary.files - 1; i++) { - String fileName = summary.tableId + "-" + direction.name().toLowerCase() + "-" + i; + String fileName = summary.tableId + "-" + toLowerCaseLocalized(direction.name()) + "-" + i; state.handleStreamEvent(new ProgressEvent(state.id(), new ProgressInfo((InetAddressAndPort) s.peer, 0, fileName, direction, fileSize, fileSize, fileSize))); counter += fileSize; } @@ -199,7 +200,7 @@ public class StreamingVirtualTableTest extends CQLTester for (StreamSummary summary : summaries) { long fileSize = summary.totalSize / summary.files; - String fileName = summary.tableId + "-" + direction.name().toLowerCase() + "-" + summary.files; + String fileName = summary.tableId + "-" + toLowerCaseLocalized(direction.name()) + "-" + summary.files; state.handleStreamEvent(new ProgressEvent(state.id(), new ProgressInfo((InetAddressAndPort) s.peer, 0, fileName, direction, fileSize, fileSize, fileSize))); counter += fileSize; } diff --git a/test/unit/org/apache/cassandra/index/sai/analyzer/filter/BasicFiltersTest.java b/test/unit/org/apache/cassandra/index/sai/analyzer/filter/BasicFiltersTest.java index 01faf488c1..9e7886e9bb 100644 --- a/test/unit/org/apache/cassandra/index/sai/analyzer/filter/BasicFiltersTest.java +++ b/test/unit/org/apache/cassandra/index/sai/analyzer/filter/BasicFiltersTest.java @@ -25,6 +25,7 @@ import org.junit.Test; import org.apache.cassandra.index.sai.SAITester; import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.junit.Assert.assertEquals; public class BasicFiltersTest @@ -37,7 +38,7 @@ public class BasicFiltersTest for (int count = 0; count < SAITester.getRandom().nextIntBetween(100, 1000); count++) { String actual = SAITester.getRandom().nextTextString(10, 50); - assertEquals(actual.toLowerCase(), lowerCase.process(actual)); + assertEquals(toLowerCaseLocalized(actual), lowerCase.process(actual)); } } diff --git a/test/unit/org/apache/cassandra/index/sasi/analyzer/DelimiterAnalyzerTest.java b/test/unit/org/apache/cassandra/index/sasi/analyzer/DelimiterAnalyzerTest.java index c3589d11fb..0cb57a607b 100644 --- a/test/unit/org/apache/cassandra/index/sasi/analyzer/DelimiterAnalyzerTest.java +++ b/test/unit/org/apache/cassandra/index/sasi/analyzer/DelimiterAnalyzerTest.java @@ -34,6 +34,7 @@ import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.junit.Assert.assertEquals; public class DelimiterAnalyzerTest @@ -59,7 +60,7 @@ public class DelimiterAnalyzerTest output.append(ByteBufferUtil.string(analyzer.next()) + (analyzer.hasNext() ? ' ' : "")); Assert.assertEquals(testString, output.toString()); - Assert.assertFalse(testString.toLowerCase().equals(output.toString())); + Assert.assertFalse(toLowerCaseLocalized(testString).equals(output.toString())); } @Test @@ -82,7 +83,7 @@ public class DelimiterAnalyzerTest output.append(ByteBufferUtil.string(analyzer.next()) + (analyzer.hasNext() ? ',' : "")); Assert.assertEquals("Nip,it,in,the,bud", output.toString()); - Assert.assertFalse(testString.toLowerCase().equals(output.toString())); + Assert.assertFalse(toLowerCaseLocalized(testString).equals(output.toString())); } @Test(expected = ConfigurationException.class) diff --git a/test/unit/org/apache/cassandra/index/sasi/analyzer/NonTokenizingAnalyzerTest.java b/test/unit/org/apache/cassandra/index/sasi/analyzer/NonTokenizingAnalyzerTest.java index ba67853c43..abe4978132 100644 --- a/test/unit/org/apache/cassandra/index/sasi/analyzer/NonTokenizingAnalyzerTest.java +++ b/test/unit/org/apache/cassandra/index/sasi/analyzer/NonTokenizingAnalyzerTest.java @@ -26,6 +26,8 @@ import org.apache.cassandra.utils.ByteBufferUtil; import org.junit.Assert; import org.junit.Test; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * Tests for the non-tokenizing analyzer */ @@ -45,7 +47,7 @@ public class NonTokenizingAnalyzerTest ByteBuffer analyzed = null; while (analyzer.hasNext()) analyzed = analyzer.next(); - Assert.assertTrue(testString.toLowerCase().equals(ByteBufferUtil.string(analyzed))); + Assert.assertTrue(toLowerCaseLocalized(testString).equals(ByteBufferUtil.string(analyzed))); } @Test @@ -61,7 +63,7 @@ public class NonTokenizingAnalyzerTest ByteBuffer analyzed = null; while (analyzer.hasNext()) analyzed = analyzer.next(); - Assert.assertFalse(testString.toLowerCase().equals(ByteBufferUtil.string(analyzed))); + Assert.assertFalse(toLowerCaseLocalized(testString).equals(ByteBufferUtil.string(analyzed))); } @Test diff --git a/test/unit/org/apache/cassandra/service/reads/repair/AbstractReadRepairTest.java b/test/unit/org/apache/cassandra/service/reads/repair/AbstractReadRepairTest.java index fa6783566c..b2ff6723ee 100644 --- a/test/unit/org/apache/cassandra/service/reads/repair/AbstractReadRepairTest.java +++ b/test/unit/org/apache/cassandra/service/reads/repair/AbstractReadRepairTest.java @@ -83,6 +83,7 @@ import static org.apache.cassandra.locator.ReplicaPlans.forReadRepair; import static org.apache.cassandra.locator.ReplicaUtils.FULL_RANGE; import static org.apache.cassandra.net.Verb.INTERNAL_RSP; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; @Ignore public abstract class AbstractReadRepairTest @@ -288,7 +289,7 @@ public abstract class AbstractReadRepairTest String ksName = "ks"; String ddl = String.format("CREATE TABLE tbl (k int primary key, v text) WITH read_repair='%s'", - repairStrategy.toString().toLowerCase()); + toLowerCaseLocalized(repairStrategy.toString())); cfm = CreateTableStatement.parse(ddl, ksName).build(); assert cfm.params.readRepair == repairStrategy; diff --git a/test/unit/org/apache/cassandra/tools/TopPartitionsTest.java b/test/unit/org/apache/cassandra/tools/TopPartitionsTest.java index 90b431cc7f..9a218727b9 100644 --- a/test/unit/org/apache/cassandra/tools/TopPartitionsTest.java +++ b/test/unit/org/apache/cassandra/tools/TopPartitionsTest.java @@ -43,9 +43,9 @@ import org.apache.cassandra.metrics.Sampler; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.Util; - import static java.lang.String.format; import static org.apache.cassandra.cql3.QueryProcessor.executeInternal; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -56,7 +56,7 @@ import static org.junit.Assert.assertTrue; */ public class TopPartitionsTest { - public static String KEYSPACE = TopPartitionsTest.class.getSimpleName().toLowerCase(); + public static String KEYSPACE = toLowerCaseLocalized(TopPartitionsTest.class.getSimpleName()); public static String TABLE = "test"; @BeforeClass diff --git a/tools/stress/src/org/apache/cassandra/stress/StressAction.java b/tools/stress/src/org/apache/cassandra/stress/StressAction.java index 5cf429bcdc..729090709f 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressAction.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressAction.java @@ -40,6 +40,7 @@ import org.jctools.queues.SpscUnboundedArrayQueue; import com.google.common.util.concurrent.Uninterruptibles; import static org.apache.cassandra.utils.Clock.Global.nanoTime; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public class StressAction implements Runnable { @@ -217,7 +218,7 @@ public class StressAction implements Runnable output.println(String.format("Running %s with %d threads %s", operations.desc(), threadCount, - durationUnits != null ? duration + " " + durationUnits.toString().toLowerCase() + durationUnits != null ? duration + " " + toLowerCaseLocalized(durationUnits.toString()) : opCount > 0 ? "for " + opCount + " iteration" : "until stderr of mean < " + settings.command.targetUncertainty)); final WorkManager workManager; diff --git a/tools/stress/src/org/apache/cassandra/stress/StressGraph.java b/tools/stress/src/org/apache/cassandra/stress/StressGraph.java index 9b38bb80f2..7694052599 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressGraph.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressGraph.java @@ -40,6 +40,8 @@ import org.apache.cassandra.stress.report.StressMetrics; import org.apache.cassandra.stress.settings.StressSettings; import org.apache.cassandra.utils.JsonUtils; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class StressGraph { private StressSettings stressSettings; @@ -200,7 +202,7 @@ public class StressGraph continue; } // the graphing js expects lower case names - json.put(parts[0].trim().toLowerCase(), parts[1].trim()); + json.put(toLowerCaseLocalized(parts[0].trim()), parts[1].trim()); } else if (mode == ReadingMode.NEXTITERATION) { diff --git a/tools/stress/src/org/apache/cassandra/stress/StressProfile.java b/tools/stress/src/org/apache/cassandra/stress/StressProfile.java index 5fe3b9dca7..eb95560a35 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressProfile.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressProfile.java @@ -62,6 +62,9 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.error.YAMLException; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class StressProfile implements Serializable { private String keyspaceCql; @@ -357,7 +360,7 @@ public class StressProfile implements Serializable StressSettings settings, boolean isWarmup) { - name = name.toLowerCase(); + name = toLowerCaseLocalized(name); if (!queries.containsKey(name)) throw new IllegalArgumentException("No query defined with name " + name); @@ -373,10 +376,10 @@ public class StressProfile implements Serializable Map args = new HashMap<>(); for (Map.Entry e : queries.entrySet()) { - stmts.put(e.getKey().toLowerCase(), jclient.prepare(e.getValue().cql)); - args.put(e.getKey().toLowerCase(), e.getValue().fields == null + stmts.put(toLowerCaseLocalized(e.getKey()), jclient.prepare(e.getValue().cql)); + args.put(toLowerCaseLocalized(e.getKey()), e.getValue().fields == null ? SchemaStatement.ArgSelect.MULTIROW - : SchemaStatement.ArgSelect.valueOf(e.getValue().fields.toUpperCase())); + : SchemaStatement.ArgSelect.valueOf(toUpperCaseLocalized(e.getValue().fields))); } queryStatements = stmts; argSelects = args; @@ -395,7 +398,7 @@ public class StressProfile implements Serializable if (statement == null) return false; - if (!statement.getQueryString().toUpperCase().startsWith("UPDATE")) + if (!toUpperCaseLocalized(statement.getQueryString()).startsWith("UPDATE")) return false; ModificationStatement.Parsed modificationStatement; @@ -758,7 +761,7 @@ public class StressProfile implements Serializable static Generator getGenerator(final String name, final String type, final String collectionType, GeneratorConfig config) { - switch (type.toUpperCase()) + switch (toUpperCaseLocalized(type)) { case "ASCII": case "TEXT": @@ -848,7 +851,7 @@ public class StressProfile implements Serializable } } for (Map.Entry e : reinsert) - map.put(e.getKey().toLowerCase(), e.getValue()); + map.put(toLowerCaseLocalized(e.getKey()), e.getValue()); } /* Quote a identifier if it contains uppercase letters */ diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/CliOption.java b/tools/stress/src/org/apache/cassandra/stress/settings/CliOption.java index 550467171d..a3f649d6b7 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/CliOption.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/CliOption.java @@ -24,6 +24,8 @@ package org.apache.cassandra.stress.settings; import java.util.HashMap; import java.util.Map; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public enum CliOption { POP("Population distribution and intra-partition visit order", SettingsPopulation.helpPrinter()), @@ -50,7 +52,7 @@ public enum CliOption final Map lookup = new HashMap<>(); for (CliOption cmd : values()) { - lookup.put("-" + cmd.toString().toLowerCase(), cmd); + lookup.put("-" + toLowerCaseLocalized(cmd.toString()), cmd); if (cmd.extraName != null) lookup.put(cmd.extraName, cmd); } @@ -59,7 +61,7 @@ public enum CliOption public static CliOption get(String command) { - return LOOKUP.get(command.toLowerCase()); + return LOOKUP.get(toLowerCaseLocalized(command)); } public final String extraName; diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/Command.java b/tools/stress/src/org/apache/cassandra/stress/settings/Command.java index c99afabbed..849335c309 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/Command.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/Command.java @@ -28,6 +28,8 @@ import java.util.Map; import com.google.common.collect.ImmutableList; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public enum Command { @@ -78,7 +80,7 @@ public enum Command public static Command get(String command) { - return LOOKUP.get(command.toLowerCase()); + return LOOKUP.get(toLowerCaseLocalized(command)); } public final boolean updates; @@ -98,12 +100,12 @@ public enum Command this.updates = updates; this.category = category; List names = new ArrayList<>(); - names.add(this.toString().toLowerCase()); - names.add(this.toString().replaceAll("_", "").toLowerCase()); + names.add(toLowerCaseLocalized(this.toString())); + names.add(toLowerCaseLocalized(this.toString().replaceAll("_", ""))); if (extra != null) { - names.add(extra.toLowerCase()); - names.add(extra.replaceAll("_", "").toLowerCase()); + names.add(toLowerCaseLocalized(extra)); + names.add(toLowerCaseLocalized(extra.replaceAll("_", ""))); } this.names = ImmutableList.copyOf(names); this.description = description; diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/OptionDistribution.java b/tools/stress/src/org/apache/cassandra/stress/settings/OptionDistribution.java index cc93323c88..040e9f2a1d 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/OptionDistribution.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/OptionDistribution.java @@ -34,6 +34,8 @@ import org.apache.commons.math3.random.JDKRandomGenerator; import org.apache.cassandra.stress.generate.*; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + /** * For selecting a mathematical distribution */ @@ -73,7 +75,7 @@ public class OptionDistribution extends Option @Override public boolean accept(String param) { - if (!param.toLowerCase().startsWith(prefix)) + if (!toLowerCaseLocalized(param).startsWith(prefix)) return false; spec = param.substring(prefix.length()); return true; @@ -86,7 +88,7 @@ public class OptionDistribution extends Option throw new IllegalArgumentException("Illegal distribution specification: " + spec); boolean inverse = m.group(1).equals("~"); String name = m.group(2); - Impl impl = LOOKUP.get(name.toLowerCase()); + Impl impl = LOOKUP.get(toLowerCaseLocalized(name)); if (impl == null) throw new IllegalArgumentException("Illegal distribution type: " + name); List params = new ArrayList<>(); @@ -181,7 +183,7 @@ public class OptionDistribution extends Option public static long parseLong(String value) { long multiplier = 1; - value = value.trim().toLowerCase(); + value = toLowerCaseLocalized(value.trim()); switch (value.charAt(value.length() - 1)) { case 'b': diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/OptionEnumProbabilities.java b/tools/stress/src/org/apache/cassandra/stress/settings/OptionEnumProbabilities.java index c218176469..17cc5cff2e 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/OptionEnumProbabilities.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/OptionEnumProbabilities.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; public final class OptionEnumProbabilities extends OptionMulti { @@ -48,7 +49,7 @@ public final class OptionEnumProbabilities extends OptionMulti final T opt; OptMatcher(T opt, String defaultValue) { - super(opt.toString().toLowerCase() + "=", "[0-9]+(\\.[0-9]+)?", defaultValue, "Performs this many " + opt + " operations out of total", false); + super(toLowerCaseLocalized(opt.toString()) + "=", "[0-9]+(\\.[0-9]+)?", defaultValue, "Performs this many " + opt + " operations out of total", false); this.opt = opt; } } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java index af10719a6f..234cb415e1 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java @@ -34,6 +34,9 @@ import org.apache.cassandra.stress.util.JavaDriverClient; import org.apache.cassandra.stress.util.ResultLogger; import org.apache.cassandra.db.ConsistencyLevel; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + // Generic command settings - common to read/write/etc public abstract class SettingsCommand implements Serializable { @@ -68,9 +71,9 @@ public abstract class SettingsCommand implements Serializable public SettingsCommand(Command type, Options options, Count count, Duration duration, Uncertainty uncertainty) { this.type = type; - this.consistencyLevel = ConsistencyLevel.valueOf(options.consistencyLevel.value().toUpperCase()); + this.consistencyLevel = ConsistencyLevel.valueOf(toUpperCaseLocalized(options.consistencyLevel.value())); this.noWarmup = options.noWarmup.setByUser(); - this.truncate = TruncateWhen.valueOf(options.truncate.value().toUpperCase()); + this.truncate = TruncateWhen.valueOf(toUpperCaseLocalized(options.truncate.value())); if (count != null) { @@ -85,7 +88,7 @@ public abstract class SettingsCommand implements Serializable { this.count = -1; this.duration = Long.parseLong(duration.duration.value().substring(0, duration.duration.value().length() - 1)); - switch (duration.duration.value().toLowerCase().charAt(duration.duration.value().length() - 1)) + switch (toLowerCaseLocalized(duration.duration.value()).charAt(duration.duration.value().length() - 1)) { case 's': this.durationUnits = TimeUnit.SECONDS; @@ -178,7 +181,7 @@ public abstract class SettingsCommand implements Serializable public void printSettings(ResultLogger out) { - out.printf(" Type: %s%n", type.toString().toLowerCase()); + out.printf(" Type: %s%n", toLowerCaseLocalized(type.toString())); out.printf(" Count: %,d%n", count); if (durationUnits != null) { @@ -226,11 +229,11 @@ public abstract class SettingsCommand implements Serializable static void printHelp(Command type) { - printHelp(type.toString().toLowerCase()); + printHelp(toLowerCaseLocalized(type.toString())); } static void printHelp(String type) { - GroupedOptions.printOptions(System.out, type.toLowerCase(), new Uncertainty(), new Count(), new Duration()); + GroupedOptions.printOptions(System.out, toLowerCaseLocalized(type), new Uncertainty(), new Count(), new Duration()); } } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java index 88755765db..d366d963b9 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java @@ -41,6 +41,8 @@ import org.apache.cassandra.stress.operations.predefined.PredefinedOperation; import org.apache.cassandra.stress.report.Timer; import org.apache.cassandra.stress.util.ResultLogger; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + // Settings unique to the mixed command type public class SettingsCommandPreDefined extends SettingsCommand { @@ -146,12 +148,12 @@ public class SettingsCommandPreDefined extends SettingsCommand static void printHelp(Command type) { - printHelp(type.toString().toLowerCase()); + printHelp(toLowerCaseLocalized(type.toString())); } static void printHelp(String type) { - GroupedOptions.printOptions(System.out, type.toLowerCase(), new Uncertainty(), new Count(), new Duration()); + GroupedOptions.printOptions(System.out, toLowerCaseLocalized(type), new Uncertainty(), new Count(), new Duration()); } static Runnable helpPrinter(final Command type) diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java index ae77e0a780..338d2572e2 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java @@ -29,6 +29,8 @@ import java.util.Map; import org.apache.cassandra.stress.util.MultiResultLogger; import org.apache.cassandra.stress.util.ResultLogger; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class SettingsLog implements Serializable { public static enum Level @@ -66,7 +68,7 @@ public class SettingsLog implements Serializable intervalMillis = 1000 * Integer.parseInt(interval); if (intervalMillis <= 0) throw new IllegalArgumentException("Log interval must be greater than zero"); - level = Level.valueOf(options.level.value().toUpperCase()); + level = Level.valueOf(toUpperCaseLocalized(options.level.value())); } public MultiResultLogger getOutput() throws FileNotFoundException diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMisc.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMisc.java index 1f21a61da2..2cb5491276 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMisc.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMisc.java @@ -36,6 +36,8 @@ import com.google.common.io.Resources; import org.apache.cassandra.stress.generate.Distribution; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + class SettingsMisc implements Serializable { @@ -164,13 +166,13 @@ class SettingsMisc implements Serializable System.out.println("---Commands---"); for (Command cmd : Command.values()) { - System.out.println(String.format("%-20s : %s", cmd.toString().toLowerCase(), cmd.description)); + System.out.println(String.format("%-20s : %s", toLowerCaseLocalized(cmd.toString()), cmd.description)); } System.out.println(); System.out.println("---Options---"); for (CliOption cmd : CliOption.values()) { - System.out.println(String.format("-%-20s : %s", cmd.toString().toLowerCase(), cmd.description)); + System.out.println(String.format("-%-20s : %s", toLowerCaseLocalized(cmd.toString()), cmd.description)); } } @@ -201,7 +203,7 @@ class SettingsMisc implements Serializable System.out.println(" " + cmd.names.toString().replaceAll("\\[|\\]", "")); System.out.println("Options:"); for (CliOption op : CliOption.values()) - System.out.println(" -" + op.toString().toLowerCase() + (op.extraName != null ? ", " + op.extraName : "")); + System.out.println(" -" + toLowerCaseLocalized(op.toString()) + (op.extraName != null ? ", " + op.extraName : "")); }; } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java index 5f2e7f68b9..a8303ed64f 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java @@ -36,6 +36,7 @@ import org.apache.cassandra.stress.util.ResultLogger; import static java.lang.String.format; import static org.apache.cassandra.stress.settings.SettingsCredentials.CQL_PASSWORD_PROPERTY_KEY; import static org.apache.cassandra.stress.settings.SettingsCredentials.CQL_USERNAME_PROPERTY_KEY; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; public class SettingsMode implements Serializable { @@ -79,7 +80,7 @@ public class SettingsMode implements Serializable : ProtocolVersion.fromInt(Integer.parseInt(opts.protocolVersion.value())); api = ConnectionAPI.JAVA_DRIVER_NATIVE; style = opts.useUnPrepared.setByUser() ? ConnectionStyle.CQL : ConnectionStyle.CQL_PREPARED; - compression = ProtocolOptions.Compression.valueOf(opts.useCompression.value().toUpperCase()).name(); + compression = ProtocolOptions.Compression.valueOf(toUpperCaseLocalized(opts.useCompression.value())).name(); username = opts.user.setByUser() ? opts.user.value() : credentials.cqlUsername; password = opts.password.setByUser() ? opts.password.value() : credentials.cqlPassword; maxPendingPerConnection = opts.maxPendingPerConnection.value().isEmpty() ? null : Integer.valueOf(opts.maxPendingPerConnection.value()); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java index 66984edb35..b25b7d2e16 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java @@ -32,6 +32,8 @@ import org.apache.cassandra.stress.generate.DistributionFactory; import org.apache.cassandra.stress.generate.PartitionGenerator; import org.apache.cassandra.stress.util.ResultLogger; +import static org.apache.cassandra.utils.LocalizeString.toUpperCaseLocalized; + public class SettingsPopulation implements Serializable { @@ -48,7 +50,7 @@ public class SettingsPopulation implements Serializable private SettingsPopulation(GenerateOptions options, DistributionOptions dist, SequentialOptions pop) { - this.order = !options.contents.setByUser() ? PartitionGenerator.Order.ARBITRARY : PartitionGenerator.Order.valueOf(options.contents.value().toUpperCase()); + this.order = !options.contents.setByUser() ? PartitionGenerator.Order.ARBITRARY : PartitionGenerator.Order.valueOf(toUpperCaseLocalized(options.contents.value())); if (dist != null) { this.distribution = dist.seed.get(); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java index 9fbec4139d..6aea048b4c 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java @@ -29,6 +29,8 @@ import org.apache.cassandra.stress.util.JavaDriverClient; import org.apache.cassandra.stress.util.ResultLogger; import org.apache.cassandra.transport.SimpleClient; +import static org.apache.cassandra.utils.LocalizeString.toLowerCaseLocalized; + public class StressSettings implements Serializable { public final SettingsCommand command; @@ -247,7 +249,7 @@ public class StressSettings implements Serializable { if (i > 0) putParam(key, params.toArray(new String[0]), r); - key = args[i].toLowerCase(); + key = toLowerCaseLocalized(args[i]); params.clear(); } else