diff --git a/CHANGES.txt b/CHANGES.txt index 291905f64e..8125e38826 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -47,6 +47,7 @@ * remove schema agreement checking from all external APIs (Thrift, CQL and CQL3) (CASSANDRA-4487) * add Murmur3Partitioner and make it default for new installations (CASSANDRA-3772) * (cql3) update pseudo-map syntax to use map syntax (CASSANDRA-4497) + * Finer grained exceptions hierarchy and provides error code with exceptions (CASSANDRA-3979) 1.1.5 diff --git a/doc/native_protocol.spec b/doc/native_protocol.spec index 9c30db96bb..d19963b689 100644 --- a/doc/native_protocol.spec +++ b/doc/native_protocol.spec @@ -255,8 +255,9 @@ Table of Contents 4.2.1. ERROR Indicates an error processing a request. The body of the message will be an - error code ([int]) followed by a [string] error message. The error codes are - defined in Section 6. + error code ([int]) followed by a [string] error message. Then, depending on + the exception, more content may follow. The error codes are defined in + Section 6, along with their additional content if any. 4.2.2. READY @@ -404,11 +405,70 @@ Table of Contents 6. Error codes - The currently supported errors are: - 0x0000 Server error - 0x0001 Protocol error - 0x0002 Authentication error - 0x0100 Unavailable exception - 0x0101 Timeout exception - 0x0102 Schema disagreement exception - 0x0200 Request exception + The supported error codes are described below: + 0x0000 Server error: something unexpected happened. This indicates a + server-side bug. + 0x000A Protocol error: some client message triggered a protocol + violation (for instance a QUERY message is sent before a STARTUP + one has been sent) + + 0x1000 Unavailable exception. The rest of the ERROR message body will be + + where: + is a [string] representing the consistency level of the + query having triggered the exception. + is an [int] representing the number of node that + should be alive to respect + is an [int] representing the number of replica that + were known to be alive when the request has been + processed (since an unavailable exception has been + triggered, there will be < ) + 0x1001 Overloaded: the request cannot be processed because the + coordinator node is overloaded + 0x1002 Is_bootstrapping: the request was a read request but the + coordinator node is bootstrapping + 0x1003 Truncate_error: error during a truncation error. + 0x1100 Write_timeout: Timeout exception during a write request. The rest + of the ERROR message body will be + + where: + is a [string] representing the consistency level of the + query having triggered the exception. + is an [int] representing the number of nodes having + acknowledged the request. + is the number of replica whose acknowledgement is + required to achieve . + 0x1200 Read_timeout: Timeout exception during a read request. The rest + of the ERROR message body will be + + where: + is a [string] representing the consistency level of the + query having triggered the exception. + is an [int] representing the number of nodes having + answered the request. + is the number of replica whose response is + required to achieve . Please note that it is + possible to have >= if + is false. And also in the (unlikely) + case were is achieved but the coordinator node + timeout while waiting for read-repair + acknowledgement. + is a single byte. If its value is 0, it means + the replica that was asked for data has not + responded. Otherwise, the value is != 0. + + 0x2000 Syntax_error: The submitted query has a syntax error. + 0x2100 Unauthorized: The logged user doesn't have the right to perform + the query. + 0x2200 Invalid: The query is syntactically correct but invalid. + 0x2300 Config_error: The query is invalid because of some configuration issue + 0x2400 Already_exists: The query attempted to create a keyspace or a + table that was already existing. The rest of the ERROR message + body will be where: + is a [string] representing either the keyspace that + already exists, or the keyspace in which the table that + already exists is. +
is a [string] representing the name of the table that + already exists. If the query was attempting to create a + keyspace,
will be present but will be the empty + string. diff --git a/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthenticator.java b/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthenticator.java index c8d63b7f7e..357a465bbe 100644 --- a/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthenticator.java +++ b/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthenticator.java @@ -29,7 +29,7 @@ import java.security.MessageDigest; import java.util.Map; import java.util.Properties; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.thrift.AuthenticationException; import org.apache.cassandra.utils.FBUtilities; diff --git a/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthority.java b/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthority.java index 6127370cea..88814ec5c1 100644 --- a/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthority.java +++ b/examples/simple_authentication/src/org/apache/cassandra/auth/SimpleAuthority.java @@ -29,7 +29,7 @@ import java.util.EnumSet; import java.util.List; import java.util.Properties; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.util.FileUtils; public class SimpleAuthority implements IAuthority diff --git a/src/java/org/apache/cassandra/auth/AllowAllAuthenticator.java b/src/java/org/apache/cassandra/auth/AllowAllAuthenticator.java index 238dac4aa3..af88372ba6 100644 --- a/src/java/org/apache/cassandra/auth/AllowAllAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/AllowAllAuthenticator.java @@ -19,7 +19,7 @@ package org.apache.cassandra.auth; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.thrift.AuthenticationException; public class AllowAllAuthenticator implements IAuthenticator diff --git a/src/java/org/apache/cassandra/auth/AllowAllAuthority.java b/src/java/org/apache/cassandra/auth/AllowAllAuthority.java index afa6dd4e99..5a6f86dca9 100644 --- a/src/java/org/apache/cassandra/auth/AllowAllAuthority.java +++ b/src/java/org/apache/cassandra/auth/AllowAllAuthority.java @@ -20,7 +20,7 @@ package org.apache.cassandra.auth; import java.util.EnumSet; import java.util.List; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; public class AllowAllAuthority implements IAuthority { diff --git a/src/java/org/apache/cassandra/auth/IAuthenticator.java b/src/java/org/apache/cassandra/auth/IAuthenticator.java index 3d0d683529..4f5038387e 100644 --- a/src/java/org/apache/cassandra/auth/IAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/IAuthenticator.java @@ -19,7 +19,7 @@ package org.apache.cassandra.auth; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.thrift.AuthenticationException; public interface IAuthenticator diff --git a/src/java/org/apache/cassandra/auth/IAuthority.java b/src/java/org/apache/cassandra/auth/IAuthority.java index 2ece320694..5bbdbe146f 100644 --- a/src/java/org/apache/cassandra/auth/IAuthority.java +++ b/src/java/org/apache/cassandra/auth/IAuthority.java @@ -20,7 +20,7 @@ package org.apache.cassandra.auth; import java.util.EnumSet; import java.util.List; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; /** * Cassandra's resource hierarchy looks something like: diff --git a/src/java/org/apache/cassandra/cli/CliClient.java b/src/java/org/apache/cassandra/cli/CliClient.java index bedcc59b69..090bef589b 100644 --- a/src/java/org/apache/cassandra/cli/CliClient.java +++ b/src/java/org/apache/cassandra/cli/CliClient.java @@ -34,7 +34,7 @@ import org.apache.commons.lang.StringUtils; import org.antlr.runtime.tree.Tree; import org.apache.cassandra.auth.IAuthenticator; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.db.compaction.CompactionManagerMBean; import org.apache.cassandra.db.compaction.OperationType; @@ -547,7 +547,7 @@ public class CliClient { return TypeParser.parse(compareWith); } - catch (ConfigurationException ce) + catch (RequestValidationException ce) { StringBuilder errorMessage = new StringBuilder("Unknown comparator '" + compareWith + "'. "); errorMessage.append("Available functions: "); @@ -1545,7 +1545,7 @@ public class CliClient { comparator = TypeParser.parse(defaultType); } - catch (ConfigurationException e) + catch (RequestValidationException e) { try { diff --git a/src/java/org/apache/cassandra/config/Avro.java b/src/java/org/apache/cassandra/config/Avro.java index ed914f2674..a7498d3d05 100644 --- a/src/java/org/apache/cassandra/config/Avro.java +++ b/src/java/org/apache/cassandra/config/Avro.java @@ -26,6 +26,8 @@ import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.BytesType; import org.apache.cassandra.db.marshal.TypeParser; import org.apache.cassandra.db.migration.avro.CfDef; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.locator.AbstractReplicationStrategy; import org.apache.cassandra.locator.NetworkTopologyStrategy; @@ -211,7 +213,7 @@ public class Avro AbstractType validatorType = TypeParser.parse(cd.validation_class); return new ColumnDefinition(ByteBufferUtil.clone(cd.name), validatorType, index_type, ColumnDefinition.getStringMap(cd.index_options), index_name, null); } - catch (ConfigurationException e) + catch (RequestValidationException e) { throw new RuntimeException(e); } diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java index dbe0c6fdb8..d410210f37 100644 --- a/src/java/org/apache/cassandra/config/CFMetaData.java +++ b/src/java/org/apache/cassandra/config/CFMetaData.java @@ -40,11 +40,14 @@ import org.apache.cassandra.db.*; import org.apache.cassandra.db.compaction.AbstractCompactionStrategy; import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.io.IColumnSerializer; import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.io.compress.SnappyCompressor; import org.apache.cassandra.thrift.IndexType; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.tracing.Tracing; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; @@ -287,11 +290,7 @@ public final class CFMetaData statement.applyPropertiesTo(cfmd); return cfmd; } - catch (InvalidRequestException e) - { - throw new RuntimeException(e); - } - catch (ConfigurationException e) + catch (RequestValidationException e) { throw new RuntimeException(e); } @@ -658,34 +657,34 @@ public final class CFMetaData applyImplicitDefaults(cf_def); - CFMetaData newCFMD = new CFMetaData(cf_def.keyspace, - cf_def.name, - cfType, - TypeParser.parse(cf_def.comparator_type), - cf_def.subcomparator_type == null ? null : TypeParser.parse(cf_def.subcomparator_type)); - - if (cf_def.isSetGc_grace_seconds()) { newCFMD.gcGraceSeconds(cf_def.gc_grace_seconds); } - if (cf_def.isSetMin_compaction_threshold()) { newCFMD.minCompactionThreshold(cf_def.min_compaction_threshold); } - if (cf_def.isSetMax_compaction_threshold()) { newCFMD.maxCompactionThreshold(cf_def.max_compaction_threshold); } - if (cf_def.isSetKey_alias()) { newCFMD.keyAliases(Collections.singletonList(cf_def.key_alias)); } - if (cf_def.isSetKey_validation_class()) { newCFMD.keyValidator(TypeParser.parse(cf_def.key_validation_class)); } - if (cf_def.isSetCompaction_strategy()) - newCFMD.compactionStrategyClass = createCompactionStrategy(cf_def.compaction_strategy); - if (cf_def.isSetCompaction_strategy_options()) - newCFMD.compactionStrategyOptions(new HashMap(cf_def.compaction_strategy_options)); - if (cf_def.isSetBloom_filter_fp_chance()) - newCFMD.bloomFilterFpChance(cf_def.bloom_filter_fp_chance); - if (cf_def.isSetCaching()) - newCFMD.caching(Caching.fromString(cf_def.caching)); - if (cf_def.isSetRead_repair_chance()) - newCFMD.readRepairChance(cf_def.read_repair_chance); - if (cf_def.isSetDclocal_read_repair_chance()) - newCFMD.dcLocalReadRepairChance(cf_def.dclocal_read_repair_chance); - - CompressionParameters cp = CompressionParameters.create(cf_def.compression_options); - try { + CFMetaData newCFMD = new CFMetaData(cf_def.keyspace, + cf_def.name, + cfType, + TypeParser.parse(cf_def.comparator_type), + cf_def.subcomparator_type == null ? null : TypeParser.parse(cf_def.subcomparator_type)); + + if (cf_def.isSetGc_grace_seconds()) { newCFMD.gcGraceSeconds(cf_def.gc_grace_seconds); } + if (cf_def.isSetMin_compaction_threshold()) { newCFMD.minCompactionThreshold(cf_def.min_compaction_threshold); } + if (cf_def.isSetMax_compaction_threshold()) { newCFMD.maxCompactionThreshold(cf_def.max_compaction_threshold); } + if (cf_def.isSetKey_alias()) { newCFMD.keyAliases(Collections.singletonList(cf_def.key_alias)); } + if (cf_def.isSetKey_validation_class()) { newCFMD.keyValidator(TypeParser.parse(cf_def.key_validation_class)); } + if (cf_def.isSetCompaction_strategy()) + newCFMD.compactionStrategyClass = createCompactionStrategy(cf_def.compaction_strategy); + if (cf_def.isSetCompaction_strategy_options()) + newCFMD.compactionStrategyOptions(new HashMap(cf_def.compaction_strategy_options)); + if (cf_def.isSetBloom_filter_fp_chance()) + newCFMD.bloomFilterFpChance(cf_def.bloom_filter_fp_chance); + if (cf_def.isSetCaching()) + newCFMD.caching(Caching.fromString(cf_def.caching)); + if (cf_def.isSetRead_repair_chance()) + newCFMD.readRepairChance(cf_def.read_repair_chance); + if (cf_def.isSetDclocal_read_repair_chance()) + newCFMD.dcLocalReadRepairChance(cf_def.dclocal_read_repair_chance); + + CompressionParameters cp = CompressionParameters.create(cf_def.compression_options); + return newCFMD.comment(cf_def.comment) .replicateOnWrite(cf_def.replicate_on_write) .defaultValidator(TypeParser.parse(cf_def.default_validation_class)) @@ -693,6 +692,10 @@ public final class CFMetaData .columnMetadata(ColumnDefinition.fromThrift(cf_def.column_metadata)) .compressionParameters(cp); } + catch (SyntaxException e) + { + throw new ConfigurationException(e.getMessage()); + } catch (MarshalException e) { throw new ConfigurationException(e.getMessage()); @@ -1301,6 +1304,10 @@ public final class CFMetaData return cfm; } + catch (SyntaxException e) + { + throw new RuntimeException(e); + } catch (ConfigurationException e) { throw new RuntimeException(e); diff --git a/src/java/org/apache/cassandra/config/ColumnDefinition.java b/src/java/org/apache/cassandra/config/ColumnDefinition.java index 677ddb8f1c..328d0ff427 100644 --- a/src/java/org/apache/cassandra/config/ColumnDefinition.java +++ b/src/java/org/apache/cassandra/config/ColumnDefinition.java @@ -27,6 +27,7 @@ import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.thrift.ColumnDef; import org.apache.cassandra.thrift.IndexType; @@ -115,7 +116,7 @@ public class ColumnDefinition return cd; } - public static ColumnDefinition fromThrift(ColumnDef thriftColumnDef) throws ConfigurationException + public static ColumnDefinition fromThrift(ColumnDef thriftColumnDef) throws SyntaxException, ConfigurationException { return new ColumnDefinition(ByteBufferUtil.clone(thriftColumnDef.name), TypeParser.parse(thriftColumnDef.validation_class), @@ -125,7 +126,7 @@ public class ColumnDefinition null); } - public static Map fromThrift(List thriftDefs) throws ConfigurationException + public static Map fromThrift(List thriftDefs) throws SyntaxException, ConfigurationException { if (thriftDefs == null) return new HashMap(); @@ -231,7 +232,7 @@ public class ColumnDefinition index_name, componentIndex)); } - catch (ConfigurationException e) + catch (RequestValidationException e) { throw new RuntimeException(e); } diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 75332140b1..467a6c6f89 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -40,6 +40,7 @@ import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DefsTable; import org.apache.cassandra.db.SystemTable; import org.apache.cassandra.dht.IPartitioner; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.FSWriteError; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.locator.DynamicEndpointSnitch; diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java index ac528f37e8..5b5ab77097 100644 --- a/src/java/org/apache/cassandra/config/KSMetaData.java +++ b/src/java/org/apache/cassandra/config/KSMetaData.java @@ -27,6 +27,7 @@ import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryPath; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.locator.*; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.thrift.CfDef; diff --git a/src/java/org/apache/cassandra/cql/AbstractModification.java b/src/java/org/apache/cassandra/cql/AbstractModification.java index 3d58602e52..781094f47c 100644 --- a/src/java/org/apache/cassandra/cql/AbstractModification.java +++ b/src/java/org/apache/cassandra/cql/AbstractModification.java @@ -22,8 +22,9 @@ import java.util.List; import org.apache.cassandra.db.IMutation; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnauthorizedException; public abstract class AbstractModification { @@ -102,7 +103,7 @@ public abstract class AbstractModification * @throws InvalidRequestException on the wrong request */ public abstract List prepareRowMutations(String keyspace, ClientState clientState, List variables) - throws org.apache.cassandra.thrift.InvalidRequestException; + throws InvalidRequestException, UnauthorizedException; /** * Convert statement into a list of mutations to apply on the server @@ -116,5 +117,5 @@ public abstract class AbstractModification * @throws InvalidRequestException on the wrong request */ public abstract List prepareRowMutations(String keyspace, ClientState clientState, Long timestamp, List variables) - throws org.apache.cassandra.thrift.InvalidRequestException; + throws InvalidRequestException, UnauthorizedException; } diff --git a/src/java/org/apache/cassandra/cql/AlterTableStatement.java b/src/java/org/apache/cassandra/cql/AlterTableStatement.java index 85d761967c..5210f25339 100644 --- a/src/java/org/apache/cassandra/cql/AlterTableStatement.java +++ b/src/java/org/apache/cassandra/cql/AlterTableStatement.java @@ -19,8 +19,8 @@ package org.apache.cassandra.cql; import org.apache.cassandra.config.*; import org.apache.cassandra.db.marshal.TypeParser; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.io.compress.CompressionParameters; -import org.apache.cassandra.thrift.InvalidRequestException; import java.nio.ByteBuffer; import java.util.HashMap; @@ -63,7 +63,7 @@ public class AlterTableStatement } } - public CFMetaData getCFMetaData(String keyspace) throws ConfigurationException, InvalidRequestException + public CFMetaData getCFMetaData(String keyspace) throws ConfigurationException, InvalidRequestException, SyntaxException { CFMetaData meta = Schema.instance.getCFMetaData(keyspace, columnFamily); CFMetaData cfm = meta.clone(); @@ -171,7 +171,7 @@ public class AlterTableStatement { cfm.defaultValidator(cfProps.getValidator()); } - catch (ConfigurationException e) + catch (RequestValidationException e) { throw new InvalidRequestException(String.format("Invalid validation type %s", cfProps.getProperty(CFPropDefs.KW_DEFAULTVALIDATION))); diff --git a/src/java/org/apache/cassandra/cql/Attributes.java b/src/java/org/apache/cassandra/cql/Attributes.java index 07c08b1536..faee3b8a00 100644 --- a/src/java/org/apache/cassandra/cql/Attributes.java +++ b/src/java/org/apache/cassandra/cql/Attributes.java @@ -17,7 +17,7 @@ */ package org.apache.cassandra.cql; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; /** * Class to contain attributes for statements diff --git a/src/java/org/apache/cassandra/cql/BatchStatement.java b/src/java/org/apache/cassandra/cql/BatchStatement.java index 6060aeb388..95849e7134 100644 --- a/src/java/org/apache/cassandra/cql/BatchStatement.java +++ b/src/java/org/apache/cassandra/cql/BatchStatement.java @@ -22,9 +22,10 @@ import java.util.LinkedList; import java.util.List; import org.apache.cassandra.db.IMutation; +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.InvalidRequestException; /** * A BATCH statement parsed from a CQL query. @@ -75,7 +76,7 @@ public class BatchStatement } public List getMutations(String keyspace, ClientState clientState, List variables) - throws InvalidRequestException + throws InvalidRequestException, UnauthorizedException { List batch = new LinkedList(); diff --git a/src/java/org/apache/cassandra/cql/CFPropDefs.java b/src/java/org/apache/cassandra/cql/CFPropDefs.java index 5cd14be9b2..8771c1b210 100644 --- a/src/java/org/apache/cassandra/cql/CFPropDefs.java +++ b/src/java/org/apache/cassandra/cql/CFPropDefs.java @@ -19,13 +19,14 @@ package org.apache.cassandra.cql; import com.google.common.collect.Sets; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.compaction.AbstractCompactionStrategy; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.TypeParser; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.io.compress.SnappyCompressor; -import org.apache.cassandra.thrift.InvalidRequestException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -204,14 +205,14 @@ public class CFPropDefs { * knows what they are doing (a custom comparator/validator for example), and pass it on as-is. */ - public AbstractType getComparator() throws ConfigurationException + public AbstractType getComparator() throws ConfigurationException, SyntaxException { return TypeParser.parse((comparators.get(getPropertyString(KW_COMPARATOR, "text")) != null) ? comparators.get(getPropertyString(KW_COMPARATOR, "text")) : getPropertyString(KW_COMPARATOR, "text")); } - public AbstractType getValidator() throws ConfigurationException + public AbstractType getValidator() throws ConfigurationException, SyntaxException { return TypeParser.parse((comparators.get(getPropertyString(KW_DEFAULTVALIDATION, "text")) != null) ? comparators.get(getPropertyString(KW_DEFAULTVALIDATION, "text")) diff --git a/src/java/org/apache/cassandra/cql/Cql.g b/src/java/org/apache/cassandra/cql/Cql.g index 0b7e3b6329..3c41f44b40 100644 --- a/src/java/org/apache/cassandra/cql/Cql.g +++ b/src/java/org/apache/cassandra/cql/Cql.g @@ -33,9 +33,9 @@ options { import java.util.Collections; import java.util.List; import java.util.ArrayList; + import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.Pair; - import org.apache.cassandra.thrift.ConsistencyLevel; - import org.apache.cassandra.thrift.InvalidRequestException; + import org.apache.cassandra.db.ConsistencyLevel; import static org.apache.cassandra.cql.AlterTableStatement.OperationType; } @@ -56,10 +56,10 @@ options { return recognitionErrors; } - public void throwLastRecognitionError() throws InvalidRequestException + public void throwLastRecognitionError() throws SyntaxException { if (recognitionErrors.size() > 0) - throw new InvalidRequestException(recognitionErrors.get((recognitionErrors.size()-1))); + throw new SyntaxException(recognitionErrors.get((recognitionErrors.size()-1))); } // used by UPDATE of the counter columns to validate if '-' was supplied by user @@ -72,7 +72,7 @@ options { @lexer::header { package org.apache.cassandra.cql; - import org.apache.cassandra.thrift.InvalidRequestException; + import org.apache.cassandra.exceptions.SyntaxException; } @lexer::members { @@ -104,10 +104,10 @@ options { return recognitionErrors; } - public void throwLastRecognitionError() throws InvalidRequestException + public void throwLastRecognitionError() throws SyntaxException { if (recognitionErrors.size() > 0) - throw new InvalidRequestException(recognitionErrors.get((recognitionErrors.size()-1))); + throw new SyntaxException(recognitionErrors.get((recognitionErrors.size()-1))); } } diff --git a/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java index 4c86b6e887..e0b69a479a 100644 --- a/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java @@ -26,11 +26,12 @@ import java.util.Map; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.ColumnFamilyType; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.TypeParser; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.io.compress.CompressionParameters; @@ -69,6 +70,10 @@ public class CreateColumnFamilyStatement { throw new InvalidRequestException(e.toString()); } + catch (SyntaxException e) + { + throw new InvalidRequestException(e.toString()); + } for (Map.Entry column : columns.entrySet()) { @@ -139,6 +144,12 @@ public class CreateColumnFamilyStatement ex.initCause(e); throw ex; } + catch (SyntaxException e) + { + InvalidRequestException ex = new InvalidRequestException(e.toString()); + ex.initCause(e); + throw ex; + } } return columnDefs; @@ -191,6 +202,10 @@ public class CreateColumnFamilyStatement { throw new InvalidRequestException(e.toString()); } + catch (SyntaxException e) + { + throw new InvalidRequestException(e.toString()); + } return newCFMD; } diff --git a/src/java/org/apache/cassandra/cql/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql/CreateKeyspaceStatement.java index 98b9b6ceb1..8c2aa1ba20 100644 --- a/src/java/org/apache/cassandra/cql/CreateKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql/CreateKeyspaceStatement.java @@ -20,7 +20,7 @@ package org.apache.cassandra.cql; import java.util.HashMap; import java.util.Map; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; /** A CREATE KEYSPACE statement parsed from a CQL query. */ public class CreateKeyspaceStatement diff --git a/src/java/org/apache/cassandra/cql/DeleteStatement.java b/src/java/org/apache/cassandra/cql/DeleteStatement.java index 0411419e49..e7d73e8817 100644 --- a/src/java/org/apache/cassandra/cql/DeleteStatement.java +++ b/src/java/org/apache/cassandra/cql/DeleteStatement.java @@ -28,8 +28,9 @@ import org.apache.cassandra.db.IMutation; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily; import static org.apache.cassandra.cql.QueryProcessor.validateColumnName; @@ -61,12 +62,14 @@ public class DeleteStatement extends AbstractModification return keys; } - public List prepareRowMutations(String keyspace, ClientState clientState, List variables) throws InvalidRequestException + public List prepareRowMutations(String keyspace, ClientState clientState, List variables) + throws InvalidRequestException, UnauthorizedException { return prepareRowMutations(keyspace, clientState, null, variables); } - public List prepareRowMutations(String keyspace, ClientState clientState, Long timestamp, List variables) throws InvalidRequestException + public List prepareRowMutations(String keyspace, ClientState clientState, Long timestamp, List variables) + throws InvalidRequestException, UnauthorizedException { CFMetaData metadata = validateColumnFamily(keyspace, columnFamily); diff --git a/src/java/org/apache/cassandra/cql/DropIndexStatement.java b/src/java/org/apache/cassandra/cql/DropIndexStatement.java index a8a8904f12..7df1f512e2 100644 --- a/src/java/org/apache/cassandra/cql/DropIndexStatement.java +++ b/src/java/org/apache/cassandra/cql/DropIndexStatement.java @@ -20,9 +20,10 @@ package org.apache.cassandra.cql; import java.io.IOException; import org.apache.cassandra.config.*; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.thrift.CfDef; import org.apache.cassandra.thrift.ColumnDef; -import org.apache.cassandra.thrift.InvalidRequestException; public class DropIndexStatement { diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java b/src/java/org/apache/cassandra/cql/QueryProcessor.java index 5cd2d1d1f2..fcf4d5c9d6 100644 --- a/src/java/org/apache/cassandra/cql/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java @@ -36,12 +36,24 @@ import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.marshal.MarshalException; import org.apache.cassandra.db.marshal.TypeParser; import org.apache.cassandra.dht.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.thrift.*; import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.thrift.CqlMetadata; +import org.apache.cassandra.thrift.CqlResult; +import org.apache.cassandra.thrift.CqlResultType; +import org.apache.cassandra.thrift.CqlRow; +import org.apache.cassandra.thrift.CqlPreparedResult; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.RequestType; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.ThriftValidation; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -65,7 +77,7 @@ public class QueryProcessor public static final String DEFAULT_KEY_NAME = bufferToString(CFMetaData.DEFAULT_KEY_NAME); private static List getSlice(CFMetaData metadata, SelectStatement select, List variables) - throws InvalidRequestException, TimedOutException, UnavailableException + throws InvalidRequestException, ReadTimeoutException, UnavailableException, IsBootstrappingException { QueryPath queryPath = new QueryPath(select.getColumnFamily()); List commands = new ArrayList(); @@ -111,10 +123,6 @@ public class QueryProcessor { return StorageProxy.read(commands, select.getConsistencyLevel()); } - catch (TimeoutException e) - { - throw new TimedOutException(); - } catch (IOException e) { throw new RuntimeException(e); @@ -137,7 +145,7 @@ public class QueryProcessor } private static List multiRangeSlice(CFMetaData metadata, SelectStatement select, List variables) - throws TimedOutException, UnavailableException, InvalidRequestException + throws ReadTimeoutException, UnavailableException, InvalidRequestException { List rows; IPartitioner p = StorageService.getPartitioner(); @@ -197,14 +205,6 @@ public class QueryProcessor { throw new RuntimeException(e); } - catch (org.apache.cassandra.thrift.UnavailableException e) - { - throw new UnavailableException(); - } - catch (TimeoutException e) - { - throw new TimedOutException(); - } // if start key was set and relation was "greater than" if (select.getKeyStart() != null && !select.includeStartKey() && !rows.isEmpty()) @@ -225,7 +225,7 @@ public class QueryProcessor } private static void batchUpdate(ClientState clientState, List updateStatements, ConsistencyLevel consistency, List variables ) - throws InvalidRequestException, UnavailableException, TimedOutException + throws RequestValidationException, RequestExecutionException { String globalKeyspace = clientState.getKeyspace(); List rowMutations = new ArrayList(updateStatements.size()); @@ -250,14 +250,7 @@ public class QueryProcessor validateKey(mutation.key()); } - try - { - StorageProxy.mutate(rowMutations, consistency); - } - catch (org.apache.cassandra.thrift.UnavailableException e) - { - throw new UnavailableException(); - } + StorageProxy.mutate(rowMutations, consistency); } private static IFilter filterFromSelect(SelectStatement select, CFMetaData metadata, List variables) @@ -279,7 +272,7 @@ public class QueryProcessor /* Test for SELECT-specific taboos */ private static void validateSelect(String keyspace, SelectStatement select, List variables) throws InvalidRequestException { - ThriftValidation.validateConsistencyLevel(keyspace, select.getConsistencyLevel(), RequestType.READ); + select.getConsistencyLevel().validateForRead(keyspace); // Finish key w/o start key (KEY < foo) if (!select.isKeyRange() && (select.getKeyFinish() != null)) @@ -405,7 +398,7 @@ public class QueryProcessor } public static CqlResult processStatement(CQLStatement statement,ClientState clientState, List variables ) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestExecutionException, RequestValidationException { String keyspace = null; @@ -564,14 +557,14 @@ public class QueryProcessor case INSERT: // insert uses UpdateStatement case UPDATE: UpdateStatement update = (UpdateStatement)statement.statement; - ThriftValidation.validateConsistencyLevel(keyspace, update.getConsistencyLevel(), RequestType.WRITE); + update.getConsistencyLevel().validateForWrite(keyspace); batchUpdate(clientState, Collections.singletonList(update), update.getConsistencyLevel(), variables); result.type = CqlResultType.VOID; return result; case BATCH: BatchStatement batch = (BatchStatement) statement.statement; - ThriftValidation.validateConsistencyLevel(keyspace, batch.getConsistencyLevel(), RequestType.WRITE); + batch.getConsistencyLevel().validateForWrite(keyspace); if (batch.getTimeToLive() != 0) throw new InvalidRequestException("Global TTL on the BATCH statement is not supported."); @@ -593,14 +586,7 @@ public class QueryProcessor validateKey(mutation.key()); } - try - { - StorageProxy.mutate(mutations, batch.getConsistencyLevel()); - } - catch (org.apache.cassandra.thrift.UnavailableException e) - { - throw new UnavailableException(); - } + StorageProxy.mutate(mutations, batch.getConsistencyLevel()); result.type = CqlResultType.VOID; return result; @@ -624,11 +610,11 @@ public class QueryProcessor } catch (TimeoutException e) { - throw (UnavailableException) new UnavailableException().initCause(e); + throw new TruncateException(e); } catch (IOException e) { - throw (UnavailableException) new UnavailableException().initCause(e); + throw new RuntimeException(e); } result.type = CqlResultType.VOID; @@ -819,14 +805,14 @@ public class QueryProcessor } public static CqlResult process(String queryString, ClientState clientState) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestValidationException, RequestExecutionException { logger.trace("CQL QUERY: {}", queryString); return processStatement(getStatement(queryString), clientState, new ArrayList(0)); } public static CqlPreparedResult prepare(String queryString, ClientState clientState) - throws InvalidRequestException + throws InvalidRequestException, SyntaxException { logger.trace("CQL QUERY: {}", queryString); @@ -843,7 +829,7 @@ public class QueryProcessor } public static CqlResult processPrepared(CQLStatement statement, ClientState clientState, List variables) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestValidationException, RequestExecutionException { // Check to see if there are any bound variables to verify if (!(variables.isEmpty() && (statement.boundTerms == 0))) @@ -891,7 +877,7 @@ public class QueryProcessor return keyString; } - private static CQLStatement getStatement(String queryStr) throws InvalidRequestException + private static CQLStatement getStatement(String queryStr) throws SyntaxException { try { @@ -913,14 +899,12 @@ public class QueryProcessor } catch (RuntimeException re) { - InvalidRequestException ire = new InvalidRequestException("Failed parsing statement: [" + queryStr + "] reason: " + re.getClass().getSimpleName() + " " + re.getMessage()); - ire.initCause(re); + SyntaxException ire = new SyntaxException("Failed parsing statement: [" + queryStr + "] reason: " + re.getClass().getSimpleName() + " " + re.getMessage()); throw ire; } catch (RecognitionException e) { - InvalidRequestException ire = new InvalidRequestException("Invalid or malformed CQL query string"); - ire.initCause(e); + SyntaxException ire = new SyntaxException("Invalid or malformed CQL query string: " + e.getMessage()); throw ire; } } diff --git a/src/java/org/apache/cassandra/cql/SelectStatement.java b/src/java/org/apache/cassandra/cql/SelectStatement.java index 426b63e714..69b191dcf7 100644 --- a/src/java/org/apache/cassandra/cql/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql/SelectStatement.java @@ -24,7 +24,7 @@ import java.util.Set; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; /** * Encapsulates a completely parsed SELECT query, including the target diff --git a/src/java/org/apache/cassandra/cql/Term.java b/src/java/org/apache/cassandra/cql/Term.java index fbd55fbba3..8cd312b48b 100644 --- a/src/java/org/apache/cassandra/cql/Term.java +++ b/src/java/org/apache/cassandra/cql/Term.java @@ -26,7 +26,7 @@ import org.apache.cassandra.db.marshal.FloatType; import org.apache.cassandra.db.marshal.IntegerType; import org.apache.cassandra.db.marshal.LexicalUUIDType; import org.apache.cassandra.db.marshal.MarshalException; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; /** A term parsed from a CQL statement. */ public class Term diff --git a/src/java/org/apache/cassandra/cql/UpdateStatement.java b/src/java/org/apache/cassandra/cql/UpdateStatement.java index 54e5a1f274..750cc09a29 100644 --- a/src/java/org/apache/cassandra/cql/UpdateStatement.java +++ b/src/java/org/apache/cassandra/cql/UpdateStatement.java @@ -24,19 +24,19 @@ import org.apache.cassandra.auth.Permission; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.CounterMutation; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.IMutation; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.InvalidRequestException; import static org.apache.cassandra.cql.QueryProcessor.validateColumn; import static org.apache.cassandra.cql.QueryProcessor.validateKey; import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily; -import static org.apache.cassandra.thrift.ThriftValidation.validateCommutativeForWrite; /** * An UPDATE statement parsed from a CQL query statement. @@ -122,13 +122,15 @@ public class UpdateStatement extends AbstractModification } /** {@inheritDoc} */ - public List prepareRowMutations(String keyspace, ClientState clientState, List variables) throws InvalidRequestException + public List prepareRowMutations(String keyspace, ClientState clientState, List variables) + throws InvalidRequestException, UnauthorizedException { return prepareRowMutations(keyspace, clientState, null, variables); } /** {@inheritDoc} */ - public List prepareRowMutations(String keyspace, ClientState clientState, Long timestamp, List variables) throws InvalidRequestException + public List prepareRowMutations(String keyspace, ClientState clientState, Long timestamp, List variables) + throws InvalidRequestException, UnauthorizedException { List cfamsSeen = new ArrayList(); @@ -145,7 +147,7 @@ public class UpdateStatement extends AbstractModification CFMetaData metadata = validateColumnFamily(keyspace, columnFamily, hasCommutativeOperation); if (hasCommutativeOperation) - validateCommutativeForWrite(metadata, cLevel); + cLevel.validateCounterForWrite(metadata); QueryProcessor.validateKeyAlias(metadata, keyName); diff --git a/src/java/org/apache/cassandra/cql3/Attributes.java b/src/java/org/apache/cassandra/cql3/Attributes.java index 545024960a..00fd30be69 100644 --- a/src/java/org/apache/cassandra/cql3/Attributes.java +++ b/src/java/org/apache/cassandra/cql3/Attributes.java @@ -17,7 +17,7 @@ */ package org.apache.cassandra.cql3; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; /** * Utility class for the Parser to gather attributes for modification diff --git a/src/java/org/apache/cassandra/cql3/CFDefinition.java b/src/java/org/apache/cassandra/cql3/CFDefinition.java index 51f7ceb730..8e91adeea2 100644 --- a/src/java/org/apache/cassandra/cql3/CFDefinition.java +++ b/src/java/org/apache/cassandra/cql3/CFDefinition.java @@ -29,7 +29,7 @@ import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.ColumnToCollectionType; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.db.marshal.UTF8Type; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; /** diff --git a/src/java/org/apache/cassandra/cql3/CFPropDefs.java b/src/java/org/apache/cassandra/cql3/CFPropDefs.java index b7207feabf..bd452a33fc 100644 --- a/src/java/org/apache/cassandra/cql3/CFPropDefs.java +++ b/src/java/org/apache/cassandra/cql3/CFPropDefs.java @@ -19,7 +19,7 @@ package org.apache.cassandra.cql3; import com.google.common.collect.Sets; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.compaction.AbstractCompactionStrategy; import org.apache.cassandra.io.compress.CompressionParameters; import org.slf4j.Logger; diff --git a/src/java/org/apache/cassandra/cql3/CQLStatement.java b/src/java/org/apache/cassandra/cql3/CQLStatement.java index c1daa52b4a..d0889bce07 100644 --- a/src/java/org/apache/cassandra/cql3/CQLStatement.java +++ b/src/java/org/apache/cassandra/cql3/CQLStatement.java @@ -22,9 +22,7 @@ import java.util.List; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.exceptions.*; public interface CQLStatement { @@ -38,7 +36,7 @@ public interface CQLStatement * * @param state the current client state */ - public void checkAccess(ClientState state) throws InvalidRequestException; + public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException; /** * Perform additional validation required by the statment. @@ -46,7 +44,7 @@ public interface CQLStatement * * @param state the current client state */ - public void validate(ClientState state) throws InvalidRequestException; + public void validate(ClientState state) throws RequestValidationException; /** * Execute the statement and return the resulting result or null if there is no result. @@ -55,5 +53,5 @@ public interface CQLStatement * @param variables the values for bounded variables. The implementation * can assume that each bound term have a corresponding value. */ - public ResultMessage execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException; + public ResultMessage execute(ClientState state, List variables) throws RequestValidationException, RequestExecutionException; } diff --git a/src/java/org/apache/cassandra/cql3/ColumnNameBuilder.java b/src/java/org/apache/cassandra/cql3/ColumnNameBuilder.java index 380153f887..4c7f434396 100644 --- a/src/java/org/apache/cassandra/cql3/ColumnNameBuilder.java +++ b/src/java/org/apache/cassandra/cql3/ColumnNameBuilder.java @@ -20,7 +20,7 @@ package org.apache.cassandra.cql3; import java.nio.ByteBuffer; import java.util.List; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; /** * Build a potentially composite column name. diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index 8c43851c6f..7c02da1b07 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -36,11 +36,12 @@ options { import org.apache.cassandra.cql3.operations.*; import org.apache.cassandra.cql3.statements.*; - import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.marshal.CollectionType; + import org.apache.cassandra.exceptions.ConfigurationException; + import org.apache.cassandra.exceptions.InvalidRequestException; + import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.Pair; - import org.apache.cassandra.thrift.ConsistencyLevel; - import org.apache.cassandra.thrift.InvalidRequestException; + import org.apache.cassandra.db.ConsistencyLevel; } @members { @@ -64,10 +65,10 @@ options { return recognitionErrors; } - public void throwLastRecognitionError() throws InvalidRequestException + public void throwLastRecognitionError() throws SyntaxException { if (recognitionErrors.size() > 0) - throw new InvalidRequestException(recognitionErrors.get((recognitionErrors.size()-1))); + throw new SyntaxException(recognitionErrors.get((recognitionErrors.size()-1))); } // used by UPDATE of the counter columns to validate if '-' was supplied by user @@ -101,7 +102,7 @@ options { @lexer::header { package org.apache.cassandra.cql3; - import org.apache.cassandra.thrift.InvalidRequestException; + import org.apache.cassandra.exceptions.SyntaxException; } @lexer::members { @@ -135,10 +136,10 @@ options { return recognitionErrors; } - public void throwLastRecognitionError() throws InvalidRequestException + public void throwLastRecognitionError() throws SyntaxException { if (recognitionErrors.size() > 0) - throw new InvalidRequestException(recognitionErrors.get((recognitionErrors.size()-1))); + throw new SyntaxException(recognitionErrors.get((recognitionErrors.size()-1))); } } @@ -627,8 +628,10 @@ comparatorType returns [ParsedType t] { try { $t = new ParsedType.Custom($s.text); - } catch (ConfigurationException e) { + } catch (SyntaxException e) { addRecognitionError("Cannot parse type " + $s.text + ": " + e.getMessage()); + } catch (ConfigurationException e) { + addRecognitionError("Errot setting type " + $s.text + ": " + e.getMessage()); } } ; diff --git a/src/java/org/apache/cassandra/cql3/ParsedType.java b/src/java/org/apache/cassandra/cql3/ParsedType.java index 28e6be311d..1bb8a12eec 100644 --- a/src/java/org/apache/cassandra/cql3/ParsedType.java +++ b/src/java/org/apache/cassandra/cql3/ParsedType.java @@ -17,9 +17,10 @@ */ package org.apache.cassandra.cql3; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.marshal.*; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; public interface ParsedType { @@ -67,9 +68,9 @@ public interface ParsedType { private final AbstractType type; - public Custom(String className) throws ConfigurationException + public Custom(String className) throws SyntaxException, ConfigurationException { - this.type = TypeParser.parse(className); + this.type = TypeParser.parse(className); } public boolean isCollection() diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java index d5eb486662..3fc8d99c78 100644 --- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java @@ -30,8 +30,9 @@ import org.apache.cassandra.config.*; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.*; import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.*; +import org.apache.cassandra.thrift.SchemaDisagreementException; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.SemanticVersion; @@ -100,7 +101,7 @@ public class QueryProcessor } private static ResultMessage processStatement(CQLStatement statement, ClientState clientState, List variables) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestExecutionException, RequestValidationException { statement.checkAccess(clientState); statement.validate(clientState); @@ -109,7 +110,7 @@ public class QueryProcessor } public static ResultMessage process(String queryString, ClientState clientState) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestExecutionException, RequestValidationException { logger.trace("CQL QUERY: {}", queryString); return processStatement(getStatement(queryString, clientState).statement, clientState, Collections.emptyList()); @@ -126,18 +127,14 @@ public class QueryProcessor else return null; } - catch (UnavailableException e) + catch (RequestExecutionException e) { throw new RuntimeException(e); } - catch (InvalidRequestException e) + catch (RequestValidationException e) { throw new AssertionError(e); } - catch (TimedOutException e) - { - throw new RuntimeException(e); - } } public static UntypedResultSet resultify(String query, Row row) @@ -148,14 +145,14 @@ public class QueryProcessor ResultSet cqlRows = ss.process(Collections.singletonList(row)); return new UntypedResultSet(cqlRows); } - catch (InvalidRequestException e) + catch (RequestValidationException e) { throw new AssertionError(e); } } public static ResultMessage.Prepared prepare(String queryString, ClientState clientState) - throws InvalidRequestException + throws RequestValidationException { logger.trace("CQL QUERY: {}", queryString); @@ -171,7 +168,7 @@ public class QueryProcessor } public static ResultMessage processPrepared(CQLStatement statement, ClientState clientState, List variables) - throws UnavailableException, InvalidRequestException, TimedOutException + throws RequestExecutionException, RequestValidationException { // Check to see if there are any bound variables to verify if (!(variables.isEmpty() && (statement.getBoundsTerms() == 0))) @@ -197,7 +194,8 @@ public class QueryProcessor return cql.hashCode(); } - private static ParsedStatement.Prepared getStatement(String queryStr, ClientState clientState) throws InvalidRequestException + private static ParsedStatement.Prepared getStatement(String queryStr, ClientState clientState) + throws RequestValidationException { ParsedStatement statement = parseStatement(queryStr); @@ -208,7 +206,7 @@ public class QueryProcessor return statement.prepare(); } - public static ParsedStatement parseStatement(String queryStr) throws InvalidRequestException + public static ParsedStatement parseStatement(String queryStr) throws SyntaxException { try { @@ -230,14 +228,12 @@ public class QueryProcessor } catch (RuntimeException re) { - InvalidRequestException ire = new InvalidRequestException("Failed parsing statement: [" + queryStr + "] reason: " + re.getClass().getSimpleName() + " " + re.getMessage()); - ire.initCause(re); + SyntaxException ire = new SyntaxException("Failed parsing statement: [" + queryStr + "] reason: " + re.getClass().getSimpleName() + " " + re.getMessage()); throw ire; } catch (RecognitionException e) { - InvalidRequestException ire = new InvalidRequestException("Invalid or malformed CQL query string"); - ire.initCause(e); + SyntaxException ire = new SyntaxException("Invalid or malformed CQL query string: " + e.getMessage()); throw ire; } } diff --git a/src/java/org/apache/cassandra/cql3/Term.java b/src/java/org/apache/cassandra/cql3/Term.java index 9be6499264..3f46c35d81 100644 --- a/src/java/org/apache/cassandra/cql3/Term.java +++ b/src/java/org/apache/cassandra/cql3/Term.java @@ -21,12 +21,12 @@ import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Token; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.MarshalException; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; /** A term parsed from a CQL statement. */ public class Term diff --git a/src/java/org/apache/cassandra/cql3/operations/ColumnOperation.java b/src/java/org/apache/cassandra/cql3/operations/ColumnOperation.java index 4f36775c79..e7086c1f5f 100644 --- a/src/java/org/apache/cassandra/cql3/operations/ColumnOperation.java +++ b/src/java/org/apache/cassandra/cql3/operations/ColumnOperation.java @@ -28,7 +28,7 @@ import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.LongType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.Pair; diff --git a/src/java/org/apache/cassandra/cql3/operations/ListOperation.java b/src/java/org/apache/cassandra/cql3/operations/ListOperation.java index b4ba021368..3de984bb89 100644 --- a/src/java/org/apache/cassandra/cql3/operations/ListOperation.java +++ b/src/java/org/apache/cassandra/cql3/operations/ListOperation.java @@ -31,7 +31,7 @@ import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.Pair; import org.apache.cassandra.utils.UUIDGen; diff --git a/src/java/org/apache/cassandra/cql3/operations/MapOperation.java b/src/java/org/apache/cassandra/cql3/operations/MapOperation.java index d843fc7271..56b1038874 100644 --- a/src/java/org/apache/cassandra/cql3/operations/MapOperation.java +++ b/src/java/org/apache/cassandra/cql3/operations/MapOperation.java @@ -30,7 +30,7 @@ import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.Pair; public class MapOperation implements Operation diff --git a/src/java/org/apache/cassandra/cql3/operations/Operation.java b/src/java/org/apache/cassandra/cql3/operations/Operation.java index 13c341c1fa..52616773cb 100644 --- a/src/java/org/apache/cassandra/cql3/operations/Operation.java +++ b/src/java/org/apache/cassandra/cql3/operations/Operation.java @@ -27,7 +27,7 @@ import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.Pair; public interface Operation diff --git a/src/java/org/apache/cassandra/cql3/operations/SetOperation.java b/src/java/org/apache/cassandra/cql3/operations/SetOperation.java index 22b451727b..a31059c30a 100644 --- a/src/java/org/apache/cassandra/cql3/operations/SetOperation.java +++ b/src/java/org/apache/cassandra/cql3/operations/SetOperation.java @@ -27,7 +27,7 @@ import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.Pair; diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java index c9d4f45b3b..3204e81f73 100644 --- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java @@ -27,8 +27,8 @@ import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.ColumnToCollectionType; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.thrift.InvalidRequestException; import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily; diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java index 3757981085..c5ee1875c7 100644 --- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java @@ -26,11 +26,10 @@ import org.apache.cassandra.cql3.*; import org.apache.cassandra.db.IMutation; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.db.CounterMutation; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.RequestType; import org.apache.cassandra.thrift.ThriftValidation; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.Pair; /** @@ -63,7 +62,7 @@ public class BatchStatement extends ModificationStatement } @Override - public void checkAccess(ClientState state) throws InvalidRequestException + public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException { Set cfamsSeen = new HashSet(); for (ModificationStatement statement : statements) @@ -93,12 +92,12 @@ public class BatchStatement extends ModificationStatement if (statement.getTimeToLive() < 0) throw new InvalidRequestException("A TTL must be greater or equal to 0"); - ThriftValidation.validateConsistencyLevel(statement.keyspace(), getConsistencyLevel(), RequestType.WRITE); + getConsistencyLevel().validateForWrite(statement.keyspace()); } } public List getMutations(ClientState clientState, List variables) - throws UnavailableException, TimeoutException, InvalidRequestException + throws RequestExecutionException, RequestValidationException { Map, RowAndCounterMutation> mutations = new HashMap, RowAndCounterMutation>(); for (ModificationStatement statement : statements) diff --git a/src/java/org/apache/cassandra/cql3/statements/CFStatement.java b/src/java/org/apache/cassandra/cql3/statements/CFStatement.java index dcc75b2f96..e9244ab311 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CFStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CFStatement.java @@ -19,7 +19,7 @@ package org.apache.cassandra.cql3.statements; import org.apache.cassandra.cql3.CFName; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; /** * Abstract class for statements that apply on a given column family. diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java index 3c97f90b01..b00cea508e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java @@ -30,7 +30,8 @@ import org.apache.cassandra.config.Schema; import org.apache.cassandra.cql3.*; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.db.ColumnFamilyType; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; @@ -38,10 +39,10 @@ import org.apache.cassandra.db.marshal.ColumnToCollectionType; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.db.marshal.ReversedType; import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.CqlResult; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; /** A CREATE COLUMNFAMILY parsed from a CQL query statement. */ @@ -85,7 +86,7 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement return columnDefs; } - public void announceMigration() throws InvalidRequestException, ConfigurationException + public void announceMigration() throws RequestValidationException { MigrationManager.announceNewColumnFamily(getCFMetaData()); } @@ -97,22 +98,15 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement * @return a CFMetaData instance corresponding to the values parsed from this statement * @throws InvalidRequestException on failure to validate parsed parameters */ - public CFMetaData getCFMetaData() throws InvalidRequestException + public CFMetaData getCFMetaData() throws RequestValidationException { CFMetaData newCFMD; - try - { - newCFMD = new CFMetaData(keyspace(), - columnFamily(), - ColumnFamilyType.Standard, - comparator, - null); - applyPropertiesTo(newCFMD); - } - catch (ConfigurationException e) - { - throw new InvalidRequestException(e.getMessage()); - } + newCFMD = new CFMetaData(keyspace(), + columnFamily(), + ColumnFamilyType.Standard, + comparator, + null); + applyPropertiesTo(newCFMD); return newCFMD; } @@ -148,162 +142,155 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement /** * Transform this raw statement into a CreateColumnFamilyStatement. */ - public ParsedStatement.Prepared prepare() throws InvalidRequestException + public ParsedStatement.Prepared prepare() throws RequestValidationException { - try + // Column family name + if (!columnFamily().matches("\\w+")) + throw new InvalidRequestException(String.format("\"%s\" is not a valid column family name (must be alphanumeric character only: [0-9A-Za-z]+)", columnFamily())); + if (columnFamily().length() > Schema.NAME_LENGTH) + throw new InvalidRequestException(String.format("Column family names shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, columnFamily())); + + for (Multiset.Entry entry : definedNames.entrySet()) + if (entry.getCount() > 1) + throw new InvalidRequestException(String.format("Multiple definition of identifier %s", entry.getElement())); + + properties.validate(); + + CreateColumnFamilyStatement stmt = new CreateColumnFamilyStatement(cfName, properties); + stmt.setBoundTerms(getBoundsTerms()); + + Map definedCollections = null; + for (Map.Entry entry : definitions.entrySet()) { - // Column family name - if (!columnFamily().matches("\\w+")) - throw new InvalidRequestException(String.format("\"%s\" is not a valid column family name (must be alphanumeric character only: [0-9A-Za-z]+)", columnFamily())); - if (columnFamily().length() > Schema.NAME_LENGTH) - throw new InvalidRequestException(String.format("Column family names shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, columnFamily())); - - for (Multiset.Entry entry : definedNames.entrySet()) - if (entry.getCount() > 1) - throw new InvalidRequestException(String.format("Multiple definition of identifier %s", entry.getElement())); - - properties.validate(); - - CreateColumnFamilyStatement stmt = new CreateColumnFamilyStatement(cfName, properties); - stmt.setBoundTerms(getBoundsTerms()); - - Map definedCollections = null; - for (Map.Entry entry : definitions.entrySet()) + ColumnIdentifier id = entry.getKey(); + ParsedType pt = entry.getValue(); + if (pt.isCollection()) { - ColumnIdentifier id = entry.getKey(); - ParsedType pt = entry.getValue(); - if (pt.isCollection()) - { - if (definedCollections == null) - definedCollections = new HashMap(); - definedCollections.put(id.key, (CollectionType)pt.getType()); - } - stmt.columns.put(id, pt.getType()); // we'll remove what is not a column below + if (definedCollections == null) + definedCollections = new HashMap(); + definedCollections.put(id.key, (CollectionType)pt.getType()); } + stmt.columns.put(id, pt.getType()); // we'll remove what is not a column below + } - if (keyAliases.size() != 1) - throw new InvalidRequestException("You must specify one and only one PRIMARY KEY"); + if (keyAliases.size() != 1) + throw new InvalidRequestException("You must specify one and only one PRIMARY KEY"); - List kAliases = keyAliases.get(0); + List kAliases = keyAliases.get(0); - List> keyTypes = new ArrayList>(kAliases.size()); - for (ColumnIdentifier alias : kAliases) + List> keyTypes = new ArrayList>(kAliases.size()); + for (ColumnIdentifier alias : kAliases) + { + stmt.keyAliases.add(alias.key); + AbstractType t = getTypeAndRemove(stmt.columns, alias); + if (t instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", alias)); + keyTypes.add(t); + } + stmt.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes); + + // Handle column aliases + if (columnAliases.isEmpty()) + { + if (useCompactStorage) { - stmt.keyAliases.add(alias.key); - AbstractType t = getTypeAndRemove(stmt.columns, alias); - if (t instanceof CounterColumnType) - throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", alias)); - keyTypes.add(t); - } - stmt.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes); + // There should remain some column definition since it is a non-composite "static" CF + if (stmt.columns.isEmpty()) + throw new InvalidRequestException("No definition found that is not part of the PRIMARY KEY"); - // Handle column aliases - if (columnAliases.isEmpty()) - { - if (useCompactStorage) - { - // There should remain some column definition since it is a non-composite "static" CF - if (stmt.columns.isEmpty()) - throw new InvalidRequestException("No definition found that is not part of the PRIMARY KEY"); - - stmt.comparator = CFDefinition.definitionType; - } - else - { - List> types = new ArrayList>(definedCollections == null ? 1 : 2); - types.add(CFDefinition.definitionType); - if (definedCollections != null) - types.add(ColumnToCollectionType.getInstance(definedCollections)); - stmt.comparator = CompositeType.getInstance(types); - } + stmt.comparator = CFDefinition.definitionType; } else { - // If we use compact storage and have only one alias, it is a - // standard "dynamic" CF, otherwise it's a composite - if (useCompactStorage && columnAliases.size() == 1) + List> types = new ArrayList>(definedCollections == null ? 1 : 2); + types.add(CFDefinition.definitionType); + if (definedCollections != null) + types.add(ColumnToCollectionType.getInstance(definedCollections)); + stmt.comparator = CompositeType.getInstance(types); + } + } + else + { + // If we use compact storage and have only one alias, it is a + // standard "dynamic" CF, otherwise it's a composite + if (useCompactStorage && columnAliases.size() == 1) + { + if (definedCollections != null) + throw new InvalidRequestException("Collection types are not supported with COMPACT STORAGE"); + stmt.columnAliases.add(columnAliases.get(0).key); + stmt.comparator = getTypeAndRemove(stmt.columns, columnAliases.get(0)); + if (stmt.comparator instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", stmt.columnAliases.get(0))); + } + else + { + List> types = new ArrayList>(columnAliases.size() + 1); + for (ColumnIdentifier t : columnAliases) + { + stmt.columnAliases.add(t.key); + + AbstractType type = getTypeAndRemove(stmt.columns, t); + if (type instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", t.key)); + types.add(type); + } + + if (useCompactStorage) { if (definedCollections != null) throw new InvalidRequestException("Collection types are not supported with COMPACT STORAGE"); - stmt.columnAliases.add(columnAliases.get(0).key); - stmt.comparator = getTypeAndRemove(stmt.columns, columnAliases.get(0)); - if (stmt.comparator instanceof CounterColumnType) - throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", stmt.columnAliases.get(0))); } else { - List> types = new ArrayList>(columnAliases.size() + 1); - for (ColumnIdentifier t : columnAliases) - { - stmt.columnAliases.add(t.key); - - AbstractType type = getTypeAndRemove(stmt.columns, t); - if (type instanceof CounterColumnType) - throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", t.key)); - types.add(type); - } - - if (useCompactStorage) - { - if (definedCollections != null) - throw new InvalidRequestException("Collection types are not supported with COMPACT STORAGE"); - } - else - { - // For sparse, we must add the last UTF8 component - // and the collection type if there is one - types.add(CFDefinition.definitionType); - if (definedCollections != null) - types.add(ColumnToCollectionType.getInstance(definedCollections)); - } - - if (types.isEmpty()) - throw new IllegalStateException("Nonsensical empty parameter list for CompositeType"); - stmt.comparator = CompositeType.getInstance(types); + // For sparse, we must add the last UTF8 component + // and the collection type if there is one + types.add(CFDefinition.definitionType); + if (definedCollections != null) + types.add(ColumnToCollectionType.getInstance(definedCollections)); } + + if (types.isEmpty()) + throw new IllegalStateException("Nonsensical empty parameter list for CompositeType"); + stmt.comparator = CompositeType.getInstance(types); } + } - if (useCompactStorage && stmt.columns.size() <= 1) + if (useCompactStorage && stmt.columns.size() <= 1) + { + if (stmt.columns.isEmpty()) { - if (stmt.columns.isEmpty()) - { - if (columnAliases.isEmpty()) - throw new InvalidRequestException(String.format("COMPACT STORAGE with non-composite PRIMARY KEY require one column not part of the PRIMARY KEY (got: %s)", StringUtils.join(stmt.columns.keySet(), ", "))); + if (columnAliases.isEmpty()) + throw new InvalidRequestException(String.format("COMPACT STORAGE with non-composite PRIMARY KEY require one column not part of the PRIMARY KEY (got: %s)", StringUtils.join(stmt.columns.keySet(), ", "))); - // The only value we'll insert will be the empty one, so the default validator don't matter - stmt.defaultValidator = CFDefinition.definitionType; - // We need to distinguish between - // * I'm upgrading from thrift so the valueAlias is null - // * I've define my table with only a PK (and the column value will be empty) - // So, we use an empty valueAlias (rather than null) for the second case - stmt.valueAlias = ByteBufferUtil.EMPTY_BYTE_BUFFER; - } - else - { - Map.Entry lastEntry = stmt.columns.entrySet().iterator().next(); - stmt.defaultValidator = lastEntry.getValue(); - stmt.valueAlias = lastEntry.getKey().key; - stmt.columns.remove(lastEntry.getKey()); - } + // The only value we'll insert will be the empty one, so the default validator don't matter + stmt.defaultValidator = CFDefinition.definitionType; + // We need to distinguish between + // * I'm upgrading from thrift so the valueAlias is null + // * I've define my table with only a PK (and the column value will be empty) + // So, we use an empty valueAlias (rather than null) for the second case + stmt.valueAlias = ByteBufferUtil.EMPTY_BYTE_BUFFER; } else { - if (useCompactStorage && !columnAliases.isEmpty()) - throw new InvalidRequestException(String.format("COMPACT STORAGE with composite PRIMARY KEY allows no more than one column not part of the PRIMARY KEY (got: %s)", StringUtils.join(stmt.columns.keySet(), ", "))); - - // There is no way to insert/access a column that is not defined for non-compact storage, so - // the actual validator don't matter much (except that we want to recognize counter CF as limitation apply to them). - stmt.defaultValidator = !stmt.columns.isEmpty() && (stmt.columns.values().iterator().next() instanceof CounterColumnType) - ? CounterColumnType.instance - : CFDefinition.definitionType; + Map.Entry lastEntry = stmt.columns.entrySet().iterator().next(); + stmt.defaultValidator = lastEntry.getValue(); + stmt.valueAlias = lastEntry.getKey().key; + stmt.columns.remove(lastEntry.getKey()); } - - return new ParsedStatement.Prepared(stmt); } - catch (ConfigurationException e) + else { - throw new InvalidRequestException(e.getMessage()); + if (useCompactStorage && !columnAliases.isEmpty()) + throw new InvalidRequestException(String.format("COMPACT STORAGE with composite PRIMARY KEY allows no more than one column not part of the PRIMARY KEY (got: %s)", StringUtils.join(stmt.columns.keySet(), ", "))); + + // There is no way to insert/access a column that is not defined for non-compact storage, so + // the actual validator don't matter much (except that we want to recognize counter CF as limitation apply to them). + stmt.defaultValidator = !stmt.columns.isEmpty() && (stmt.columns.values().iterator().next() instanceof CounterColumnType) + ? CounterColumnType.instance + : CFDefinition.definitionType; } + + return new ParsedStatement.Prepared(stmt); } private AbstractType getTypeAndRemove(Map columns, ColumnIdentifier t) throws InvalidRequestException, ConfigurationException diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java index 6dc3a9f795..8f933ee1ba 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java @@ -26,13 +26,13 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.cql3.*; import org.apache.cassandra.db.index.composites.CompositesIndex; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.IndexType; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.thrift.ThriftValidation; /** A CREATE INDEX statement parsed from a CQL query. */ diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java index 0c426b3abb..34d52bd8b7 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java @@ -20,15 +20,16 @@ package org.apache.cassandra.cql3.statements; import java.util.HashMap; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.KSMetaData; import org.apache.cassandra.config.Schema; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.locator.AbstractReplicationStrategy; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.service.StorageService; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.ThriftValidation; /** A CREATE KEYSPACE statement parsed from a CQL query. */ @@ -64,7 +65,7 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement * @throws InvalidRequestException if arguments are missing or unacceptable */ @Override - public void validate(ClientState state) throws InvalidRequestException + public void validate(ClientState state) throws RequestValidationException { super.validate(state); ThriftValidation.validateKeyspaceNotSystem(name); @@ -94,24 +95,16 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement } // trial run to let ARS validate class + per-class options - try - { - AbstractReplicationStrategy.createReplicationStrategy(name, - AbstractReplicationStrategy.getClass(strategyClass), - StorageService.instance.getTokenMetadata(), - DatabaseDescriptor.getEndpointSnitch(), - strategyOptions); - } - catch (ConfigurationException e) - { - throw new InvalidRequestException(e.getMessage()); - } + AbstractReplicationStrategy.createReplicationStrategy(name, + AbstractReplicationStrategy.getClass(strategyClass), + StorageService.instance.getTokenMetadata(), + DatabaseDescriptor.getEndpointSnitch(), + strategyOptions); } public void announceMigration() throws InvalidRequestException, ConfigurationException { KSMetaData ksm = KSMetaData.newKeyspace(name, strategyClass, strategyOptions); - ThriftValidation.validateKeyspaceNotYetExisting(name); MigrationManager.announceNewKeyspace(ksm); } } diff --git a/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java b/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java index 0fb97fc08e..cd0293ae9d 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java @@ -35,9 +35,8 @@ import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.db.marshal.ListType; import org.apache.cassandra.db.marshal.MapType; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.thrift.ThriftValidation; import org.apache.cassandra.utils.Pair; @@ -63,7 +62,8 @@ public class DeleteStatement extends ModificationStatement this.toRemove = new ArrayList>(columns.size()); } - public List getMutations(ClientState clientState, List variables) throws UnavailableException, TimeoutException, InvalidRequestException + public List getMutations(ClientState clientState, List variables) + throws RequestExecutionException, RequestValidationException { // keys List keys = UpdateStatement.buildKeyNames(cfDef, processedKeys, variables); diff --git a/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java index 4f0135f215..fe84ad4505 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java @@ -17,7 +17,7 @@ */ package org.apache.cassandra.cql3.statements; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.cql3.CFName; import org.apache.cassandra.service.MigrationManager; diff --git a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java index 87ef79a1ab..5fb2883d71 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java @@ -20,8 +20,8 @@ package org.apache.cassandra.cql3.statements; import org.apache.cassandra.cql3.*; import org.apache.cassandra.config.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.thrift.InvalidRequestException; public class DropIndexStatement extends SchemaAlteringStatement { diff --git a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java index af9b0a2f71..788ffc1971 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java @@ -18,10 +18,10 @@ package org.apache.cassandra.cql3.statements; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.ThriftValidation; public class DropKeyspaceStatement extends SchemaAlteringStatement @@ -35,7 +35,7 @@ public class DropKeyspaceStatement extends SchemaAlteringStatement } @Override - public void validate(ClientState state) throws InvalidRequestException + public void validate(ClientState state) throws RequestValidationException { super.validate(state); ThriftValidation.validateKeyspaceNotSystem(keyspace); diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index a74a179a8d..8ed22e1f98 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -21,7 +21,6 @@ import java.io.IOError; import java.io.IOException; import java.nio.ByteBuffer; import java.util.*; -import java.util.concurrent.TimeoutException; import org.apache.cassandra.auth.Permission; import org.apache.cassandra.cql3.*; @@ -29,14 +28,12 @@ import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.CompositeType; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.thrift.RequestType; import org.apache.cassandra.thrift.ThriftValidation; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; /** * Abstract class for statements that apply on a given column family. @@ -62,7 +59,7 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt this.timeToLive = timeToLive; } - public void checkAccess(ClientState state) throws InvalidRequestException + public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException { state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } @@ -72,20 +69,13 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt if (timeToLive < 0) throw new InvalidRequestException("A TTL must be greater or equal to 0"); - ThriftValidation.validateConsistencyLevel(keyspace(), getConsistencyLevel(), RequestType.WRITE); + getConsistencyLevel().validateForWrite(keyspace()); } - public ResultMessage execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException + public ResultMessage execute(ClientState state, List variables) throws RequestExecutionException, RequestValidationException { - try - { - StorageProxy.mutate(getMutations(state, variables), getConsistencyLevel()); - return null; - } - catch (TimeoutException e) - { - throw new TimedOutException(); - } + StorageProxy.mutate(getMutations(state, variables), getConsistencyLevel()); + return null; } public ConsistencyLevel getConsistencyLevel() @@ -118,7 +108,8 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt return timeToLive; } - public Map readRows(List keys, ColumnNameBuilder builder, CompositeType composite) throws UnavailableException, TimeoutException, InvalidRequestException + public Map readRows(List keys, ColumnNameBuilder builder, CompositeType composite) + throws RequestExecutionException, RequestValidationException { List commands = new ArrayList(keys.size()); for (ByteBuffer key : keys) @@ -167,7 +158,8 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt * @return list of the mutations * @throws InvalidRequestException on invalid requests */ - public abstract List getMutations(ClientState clientState, List variables) throws UnavailableException, TimeoutException, InvalidRequestException; + public abstract List getMutations(ClientState clientState, List variables) + throws RequestExecutionException, RequestValidationException; public abstract ParsedStatement.Prepared prepare(CFDefinition.Name[] boundNames) throws InvalidRequestException; } diff --git a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java b/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java index 1b8663ec5a..ffcb7aed90 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java @@ -21,7 +21,7 @@ import java.util.Collections; import java.util.List; import org.apache.cassandra.cql3.*; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestValidationException; public abstract class ParsedStatement { @@ -38,7 +38,7 @@ public abstract class ParsedStatement this.boundTerms = boundTerms; } - public abstract Prepared prepare() throws InvalidRequestException; + public abstract Prepared prepare() throws RequestValidationException; public static class Prepared { diff --git a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java index 8d8535129a..f00086bdf5 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java @@ -24,12 +24,14 @@ import java.util.Map; import org.apache.cassandra.cql3.CQLStatement; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.auth.Permission; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.config.Schema; import org.apache.cassandra.cql3.CFName; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.InvalidRequestException; import com.google.common.base.Predicates; import com.google.common.collect.Maps; @@ -67,9 +69,9 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL return new Prepared(this); } - public abstract void announceMigration() throws InvalidRequestException, ConfigurationException; + public abstract void announceMigration() throws RequestValidationException; - public void checkAccess(ClientState state) throws InvalidRequestException + public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException { if (isColumnFamilyLevel) state.hasColumnFamilySchemaAccess(keyspace(), Permission.WRITE); @@ -78,10 +80,10 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL } @Override - public void validate(ClientState state) throws InvalidRequestException + public void validate(ClientState state) throws RequestValidationException {} - public ResultMessage execute(ClientState state, List variables) throws InvalidRequestException + public ResultMessage execute(ClientState state, List variables) throws RequestValidationException { try { @@ -93,7 +95,6 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL ex.initCause(e); throw ex; } - return null; } } diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index adc8b34f68..23cf2a08ab 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -20,7 +20,6 @@ package org.apache.cassandra.cql3.statements; import java.io.IOException; import java.nio.ByteBuffer; import java.util.*; -import java.util.concurrent.TimeoutException; import com.google.common.collect.AbstractIterator; import org.slf4j.Logger; @@ -31,7 +30,7 @@ import org.apache.cassandra.cql3.*; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.*; import org.apache.cassandra.db.context.CounterContext; import org.apache.cassandra.db.filter.*; @@ -39,17 +38,15 @@ import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexManager; import org.apache.cassandra.db.marshal.*; import org.apache.cassandra.dht.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.service.StorageService; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.thrift.IndexExpression; import org.apache.cassandra.thrift.IndexOperator; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.RequestType; -import org.apache.cassandra.thrift.TimedOutException; import org.apache.cassandra.thrift.ThriftValidation; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -103,7 +100,7 @@ public class SelectStatement implements CQLStatement return boundTerms; } - public void checkAccess(ClientState state) throws InvalidRequestException + public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException { state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.READ); } @@ -113,34 +110,27 @@ public class SelectStatement implements CQLStatement // Nothing to do, all validation has been done by RawStatement.prepare() } - public ResultMessage.Rows execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException + public ResultMessage.Rows execute(ClientState state, List variables) throws RequestExecutionException, RequestValidationException { return new ResultMessage.Rows(executeInternal(state, variables)); } - public ResultSet executeInternal(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException + public ResultSet executeInternal(ClientState state, List variables) throws RequestExecutionException, RequestValidationException { - try + List rows; + if (isKeyRange) { - List rows; - if (isKeyRange) - { - rows = multiRangeSlice(variables); - } - else - { - rows = getSlice(variables); - } + rows = multiRangeSlice(variables); + } + else + { + rows = getSlice(variables); + } - // Even for count, we need to process the result as it'll group some column together in sparse column families - ResultSet rset = process(rows, variables); - rset = parameters.isCount ? rset.makeCountResult() : rset; - return rset; - } - catch (TimeoutException e) - { - throw new TimedOutException(); - } + // Even for count, we need to process the result as it'll group some column together in sparse column families + ResultSet rset = process(rows, variables); + rset = parameters.isCount ? rset.makeCountResult() : rset; + return rset; } public ResultSet process(List rows) throws InvalidRequestException @@ -159,7 +149,7 @@ public class SelectStatement implements CQLStatement return cfDef.cfm.cfName; } - private List getSlice(List variables) throws InvalidRequestException, TimeoutException, UnavailableException + private List getSlice(List variables) throws RequestExecutionException, RequestValidationException { QueryPath queryPath = new QueryPath(columnFamily()); Collection keys = getKeys(variables); @@ -198,7 +188,7 @@ public class SelectStatement implements CQLStatement } } - private List multiRangeSlice(List variables) throws InvalidRequestException, TimeoutException, UnavailableException + private List multiRangeSlice(List variables) throws RequestExecutionException, RequestValidationException { List rows; IFilter filter = makeFilter(variables); @@ -896,7 +886,7 @@ public class SelectStatement implements CQLStatement public ParsedStatement.Prepared prepare() throws InvalidRequestException { CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily()); - ThriftValidation.validateConsistencyLevel(keyspace(), parameters.consistencyLevel, RequestType.READ); + parameters.consistencyLevel.validateForRead(keyspace()); if (parameters.limit <= 0) throw new InvalidRequestException("LIMIT must be strictly positive"); diff --git a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java index 451fa505e6..fceaebc7b9 100644 --- a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java @@ -24,12 +24,11 @@ import java.util.concurrent.TimeoutException; import org.apache.cassandra.auth.Permission; import org.apache.cassandra.cql3.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.ThriftValidation; -import org.apache.cassandra.thrift.UnavailableException; public class TruncateStatement extends CFStatement implements CQLStatement { @@ -43,7 +42,7 @@ public class TruncateStatement extends CFStatement implements CQLStatement return new Prepared(this); } - public void checkAccess(ClientState state) throws InvalidRequestException + public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException { state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } @@ -53,19 +52,23 @@ public class TruncateStatement extends CFStatement implements CQLStatement ThriftValidation.validateColumnFamily(keyspace(), columnFamily()); } - public ResultMessage execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException + public ResultMessage execute(ClientState state, List variables) throws InvalidRequestException, TruncateException { try { StorageProxy.truncateBlocking(keyspace(), columnFamily()); } + catch (UnavailableException e) + { + throw new TruncateException(e); + } catch (TimeoutException e) { - throw (UnavailableException) new UnavailableException().initCause(e); + throw new TruncateException(e); } catch (IOException e) { - throw (UnavailableException) new UnavailableException().initCause(e); + throw new TruncateException(e); } return null; } diff --git a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java index d34e294ad6..7d49988f76 100644 --- a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java @@ -29,16 +29,14 @@ import org.apache.cassandra.cql3.operations.ColumnOperation; import org.apache.cassandra.cql3.operations.Operation; import org.apache.cassandra.db.*; import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.Pair; import static org.apache.cassandra.cql.QueryProcessor.validateKey; import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily; -import static org.apache.cassandra.thrift.ThriftValidation.validateCommutativeForWrite; /** * An UPDATE statement parsed from a CQL query statement. @@ -102,7 +100,8 @@ public class UpdateStatement extends ModificationStatement /** {@inheritDoc} */ - public List getMutations(ClientState clientState, List variables) throws UnavailableException, TimeoutException, InvalidRequestException + public List getMutations(ClientState clientState, List variables) + throws RequestExecutionException, RequestValidationException { List keys = buildKeyNames(cfDef, processedKeys, variables); @@ -305,7 +304,7 @@ public class UpdateStatement extends ModificationStatement // Deal here with the keyspace overwrite thingy to avoid mistake CFMetaData metadata = validateColumnFamily(keyspace(), columnFamily(), hasCommutativeOperation); if (hasCommutativeOperation) - validateCommutativeForWrite(metadata, cLevel); + cLevel.validateCounterForWrite(metadata); cfDef = metadata.getCfDef(); diff --git a/src/java/org/apache/cassandra/cql3/statements/UseStatement.java b/src/java/org/apache/cassandra/cql3/statements/UseStatement.java index bab7a99842..f56c6f282c 100644 --- a/src/java/org/apache/cassandra/cql3/statements/UseStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/UseStatement.java @@ -21,9 +21,9 @@ import java.nio.ByteBuffer; import java.util.List; import org.apache.cassandra.cql3.CQLStatement; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.InvalidRequestException; public class UseStatement extends ParsedStatement implements CQLStatement { diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java index adb73cc553..caa8dbc0bc 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -60,6 +60,7 @@ import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexManager; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.dht.*; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.io.sstable.*; import org.apache.cassandra.io.sstable.Descriptor; diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java index 8e7fd9d194..b9fee054ff 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; /** * The MBean interface for ColumnFamilyStore diff --git a/src/java/org/apache/cassandra/db/ConsistencyLevel.java b/src/java/org/apache/cassandra/db/ConsistencyLevel.java new file mode 100644 index 0000000000..c7c5136f1a --- /dev/null +++ b/src/java/org/apache/cassandra/db/ConsistencyLevel.java @@ -0,0 +1,114 @@ +/* + * 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.db; + +import org.apache.cassandra.config.CFMetaData; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.locator.AbstractReplicationStrategy; +import org.apache.cassandra.locator.NetworkTopologyStrategy; +import org.apache.cassandra.utils.FBUtilities; + +public enum ConsistencyLevel +{ + ANY, + ONE, + TWO, + THREE, + QUORUM, + ALL, + LOCAL_QUORUM, + EACH_QUORUM; + + private static final String LOCAL_DC = DatabaseDescriptor.getEndpointSnitch().getDatacenter(FBUtilities.getBroadcastAddress()); + + public int blockFor(String table) + { + NetworkTopologyStrategy strategy = null; + switch (this) + { + case ONE: + return 1; + case ANY: + return 1; + case TWO: + return 2; + case THREE: + return 3; + case QUORUM: + return (Table.open(table).getReplicationStrategy().getReplicationFactor() / 2) + 1; + case ALL: + return Table.open(table).getReplicationStrategy().getReplicationFactor(); + case LOCAL_QUORUM: + strategy = (NetworkTopologyStrategy) Table.open(table).getReplicationStrategy(); + return (strategy.getReplicationFactor(LOCAL_DC) / 2) + 1; + case EACH_QUORUM: + strategy = (NetworkTopologyStrategy) Table.open(table).getReplicationStrategy(); + int n = 0; + for (String dc : strategy.getDatacenters()) + n += (strategy.getReplicationFactor(dc) / 2) + 1; + return n; + default: + throw new UnsupportedOperationException("Invalid consistency level: " + toString()); + } + } + + public void validateForRead(String table) throws InvalidRequestException + { + switch (this) + { + case ANY: + throw new InvalidRequestException("ANY ConsistencyLevel is only supported for writes"); + case LOCAL_QUORUM: + requireNetworkTopologyStrategy(table); + break; + case EACH_QUORUM: + throw new InvalidRequestException("EACH_QUORUM ConsistencyLevel is only supported for writes"); + } + } + + public void validateForWrite(String table) throws InvalidRequestException + { + switch (this) + { + case LOCAL_QUORUM: + case EACH_QUORUM: + requireNetworkTopologyStrategy(table); + break; + } + } + + public void validateCounterForWrite(CFMetaData metadata) throws InvalidRequestException + { + if (this == ConsistencyLevel.ANY) + { + throw new InvalidRequestException("Consistency level ANY is not yet supported for counter columnfamily " + metadata.cfName); + } + else if (!metadata.getReplicateOnWrite() && this != ConsistencyLevel.ONE) + { + throw new InvalidRequestException("cannot achieve CL > CL.ONE without replicate_on_write on columnfamily " + metadata.cfName); + } + } + + private void requireNetworkTopologyStrategy(String table) throws InvalidRequestException + { + AbstractReplicationStrategy strategy = Table.open(table).getReplicationStrategy(); + if (!(strategy instanceof NetworkTopologyStrategy)) + throw new InvalidRequestException(String.format("consistency level %s not compatible with replication strategy (%s)", this, strategy.getClass().getName())); + } +} diff --git a/src/java/org/apache/cassandra/db/CounterColumn.java b/src/java/org/apache/cassandra/db/CounterColumn.java index 0aa22ecaaa..9829917a59 100644 --- a/src/java/org/apache/cassandra/db/CounterColumn.java +++ b/src/java/org/apache/cassandra/db/CounterColumn.java @@ -33,13 +33,14 @@ import org.apache.cassandra.db.context.CounterContext; import org.apache.cassandra.db.context.IContext.ContextRelationship; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.MarshalException; +import org.apache.cassandra.exceptions.OverloadedException; +import org.apache.cassandra.exceptions.RequestExecutionException; import org.apache.cassandra.io.IColumnSerializer; import org.apache.cassandra.io.util.DataOutputBuffer; import org.apache.cassandra.utils.Allocator; import org.apache.cassandra.service.IWriteResponseHandler; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.*; /** @@ -357,7 +358,7 @@ public class CounterColumn extends Column return new CounterColumn(name, contextManager.markDeltaToBeCleared(value), timestamp, timestampOfLastDelete); } - private static void sendToOtherReplica(DecoratedKey key, ColumnFamily cf) throws UnavailableException, TimeoutException, IOException + private static void sendToOtherReplica(DecoratedKey key, ColumnFamily cf) throws RequestExecutionException, IOException { RowMutation rm = new RowMutation(cf.metadata().ksName, key.key); rm.add(cf); @@ -368,7 +369,7 @@ public class CounterColumn extends Column StorageProxy.performWrite(rm, ConsistencyLevel.ANY, localDataCenter, new StorageProxy.WritePerformer() { public void apply(IMutation mutation, Collection targets, IWriteResponseHandler responseHandler, String localDataCenter, ConsistencyLevel consistency_level) - throws IOException, UnavailableException + throws IOException, OverloadedException { // We should only send to the remote replica, not the local one targets.remove(local); diff --git a/src/java/org/apache/cassandra/db/CounterMutation.java b/src/java/org/apache/cassandra/db/CounterMutation.java index 601df94476..b1e48e6230 100644 --- a/src/java/org/apache/cassandra/db/CounterMutation.java +++ b/src/java/org/apache/cassandra/db/CounterMutation.java @@ -30,7 +30,7 @@ import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.io.IVersionedSerializer; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.HeapAllocator; diff --git a/src/java/org/apache/cassandra/db/CounterMutationVerbHandler.java b/src/java/org/apache/cassandra/db/CounterMutationVerbHandler.java index edd4fe38dd..f94495dd0e 100644 --- a/src/java/org/apache/cassandra/db/CounterMutationVerbHandler.java +++ b/src/java/org/apache/cassandra/db/CounterMutationVerbHandler.java @@ -23,12 +23,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.exceptions.RequestExecutionException; import org.apache.cassandra.net.IVerbHandler; import org.apache.cassandra.net.MessageIn; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.FBUtilities; public class CounterMutationVerbHandler implements IVerbHandler @@ -48,17 +47,10 @@ public class CounterMutationVerbHandler implements IVerbHandler WriteResponse response = new WriteResponse(); MessagingService.instance().sendReply(response.createMessage(), id, message.from); } - catch (UnavailableException e) + catch (RequestExecutionException e) { - // We check for UnavailableException in the coordinator now. It is - // hence reasonable to let the coordinator timeout in the very - // unlikely case we arrive here - logger.debug("counter unavailable", e); - } - catch (TimedOutException e) - { - // The coordinator node will have timeout itself so we let that goes - logger.debug("counter timeout", e); + // The coordinator will timeout on itself, so let that go + logger.debug("counter error", e); } catch (IOException e) { diff --git a/src/java/org/apache/cassandra/db/DefsTable.java b/src/java/org/apache/cassandra/db/DefsTable.java index 0c296e6565..8abe76afed 100644 --- a/src/java/org/apache/cassandra/db/DefsTable.java +++ b/src/java/org/apache/cassandra/db/DefsTable.java @@ -41,6 +41,7 @@ import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.db.migration.avro.KsDef; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/db/HintedHandOffManager.java b/src/java/org/apache/cassandra/db/HintedHandOffManager.java index bf6f594a78..22052ada69 100644 --- a/src/java/org/apache/cassandra/db/HintedHandOffManager.java +++ b/src/java/org/apache/cassandra/db/HintedHandOffManager.java @@ -44,6 +44,7 @@ import org.apache.cassandra.db.marshal.UUIDType; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Range; import org.apache.cassandra.dht.Token; +import org.apache.cassandra.exceptions.WriteTimeoutException; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.FailureDetector; import org.apache.cassandra.gms.Gossiper; @@ -125,7 +126,7 @@ public class HintedHandOffManager implements HintedHandOffManagerMBean StorageService.optionalTasks.scheduleWithFixedDelay(runnable, 10, 10, TimeUnit.MINUTES); } - private static void sendMutation(InetAddress endpoint, MessageOut message) throws TimedOutException + private static void sendMutation(InetAddress endpoint, MessageOut message) throws WriteTimeoutException { IWriteResponseHandler responseHandler = WriteResponseHandler.create(endpoint); MessagingService.instance().sendRR(message, endpoint, responseHandler); @@ -364,7 +365,7 @@ public class HintedHandOffManager implements HintedHandOffManagerMBean } deleteHint(hostIdBytes, hint.name(), hint.maxTimestamp()); } - catch (TimedOutException e) + catch (WriteTimeoutException e) { logger.info(String.format("Timed out replaying hints to %s; aborting further deliveries", endpoint)); break delivery; diff --git a/src/java/org/apache/cassandra/db/KeyspaceNotDefinedException.java b/src/java/org/apache/cassandra/db/KeyspaceNotDefinedException.java index 07f6ece919..9d07f5e9b7 100644 --- a/src/java/org/apache/cassandra/db/KeyspaceNotDefinedException.java +++ b/src/java/org/apache/cassandra/db/KeyspaceNotDefinedException.java @@ -17,7 +17,7 @@ */ package org.apache.cassandra.db; -import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.exceptions.InvalidRequestException; public class KeyspaceNotDefinedException extends InvalidRequestException { diff --git a/src/java/org/apache/cassandra/db/RangeSliceCommand.java b/src/java/org/apache/cassandra/db/RangeSliceCommand.java index 6632f39fb5..2274818f6b 100644 --- a/src/java/org/apache/cassandra/db/RangeSliceCommand.java +++ b/src/java/org/apache/cassandra/db/RangeSliceCommand.java @@ -50,11 +50,19 @@ import org.apache.cassandra.db.filter.NamesQueryFilter; import org.apache.cassandra.db.filter.SliceQueryFilter; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.dht.AbstractBounds; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.io.IVersionedSerializer; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.service.IReadCommand; -import org.apache.cassandra.thrift.*; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.TBinaryProtocol; +import org.apache.cassandra.thrift.ThriftValidation; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.thrift.TDeserializer; diff --git a/src/java/org/apache/cassandra/db/SystemTable.java b/src/java/org/apache/cassandra/db/SystemTable.java index cd64d2cc55..18dead3b04 100644 --- a/src/java/org/apache/cassandra/db/SystemTable.java +++ b/src/java/org/apache/cassandra/db/SystemTable.java @@ -28,7 +28,7 @@ import com.google.common.collect.Multimap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.cql3.UntypedResultSet; diff --git a/src/java/org/apache/cassandra/db/Table.java b/src/java/org/apache/cassandra/db/Table.java index 66fab5b65d..b700ef677e 100644 --- a/src/java/org/apache/cassandra/db/Table.java +++ b/src/java/org/apache/cassandra/db/Table.java @@ -37,6 +37,7 @@ import org.apache.cassandra.db.filter.ColumnSlice; import org.apache.cassandra.db.filter.QueryFilter; import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexManager; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.sstable.SSTableReader; import org.apache.cassandra.locator.AbstractReplicationStrategy; import org.apache.cassandra.service.StorageService; diff --git a/src/java/org/apache/cassandra/db/index/SecondaryIndex.java b/src/java/org/apache/cassandra/db/index/SecondaryIndex.java index 82b6697232..b0ffe3a884 100644 --- a/src/java/org/apache/cassandra/db/index/SecondaryIndex.java +++ b/src/java/org/apache/cassandra/db/index/SecondaryIndex.java @@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.db.IColumn; diff --git a/src/java/org/apache/cassandra/db/index/SecondaryIndexManager.java b/src/java/org/apache/cassandra/db/index/SecondaryIndexManager.java index 70a916467b..a01b0f9849 100644 --- a/src/java/org/apache/cassandra/db/index/SecondaryIndexManager.java +++ b/src/java/org/apache/cassandra/db/index/SecondaryIndexManager.java @@ -29,7 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.*; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.filter.IFilter; diff --git a/src/java/org/apache/cassandra/db/index/composites/CompositesIndex.java b/src/java/org/apache/cassandra/db/index/composites/CompositesIndex.java index f9db99f422..552d75f98a 100644 --- a/src/java/org/apache/cassandra/db/index/composites/CompositesIndex.java +++ b/src/java/org/apache/cassandra/db/index/composites/CompositesIndex.java @@ -21,12 +21,12 @@ import java.nio.ByteBuffer; import java.util.Set; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.*; import org.apache.cassandra.db.index.AbstractSimplePerColumnSecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexSearcher; import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.ConfigurationException; /** * Implements a secondary index for a column family using a second column family diff --git a/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java b/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java index e9c805d1a0..dbc32cee0d 100644 --- a/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java +++ b/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java @@ -23,7 +23,7 @@ import java.util.concurrent.ExecutionException; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.*; import org.apache.cassandra.db.index.AbstractSimplePerColumnSecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexSearcher; diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java b/src/java/org/apache/cassandra/db/marshal/AbstractType.java index 2aa957863c..5393c0cfa5 100644 --- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java +++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java @@ -22,7 +22,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.OnDiskAtom; import org.apache.cassandra.db.RangeTombstone; @@ -174,7 +174,7 @@ public abstract class AbstractType implements Comparator return false; } - public static AbstractType parseDefaultParameters(AbstractType baseType, TypeParser parser) throws ConfigurationException + public static AbstractType parseDefaultParameters(AbstractType baseType, TypeParser parser) throws SyntaxException { Map parameters = parser.getKeyValueParameters(); String reversed = parameters.get("reversed"); diff --git a/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java b/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java index 4ba73aa1f4..bb5d2fa033 100644 --- a/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java +++ b/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java @@ -23,7 +23,8 @@ import java.util.Map; import com.google.common.collect.ImmutableMap; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; public class ColumnToCollectionType extends AbstractType @@ -33,7 +34,7 @@ public class ColumnToCollectionType extends AbstractType public final Map defined; - public static ColumnToCollectionType getInstance(TypeParser parser) throws ConfigurationException + public static ColumnToCollectionType getInstance(TypeParser parser) throws SyntaxException, ConfigurationException { return getInstance(parser.getCollectionsParameters()); } diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java b/src/java/org/apache/cassandra/db/marshal/CompositeType.java index 83603eab26..fb80906f49 100644 --- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java +++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java @@ -27,12 +27,13 @@ import java.util.Map; import com.google.common.collect.ImmutableList; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.cql3.ColumnNameBuilder; import org.apache.cassandra.cql3.Relation; import org.apache.cassandra.cql3.Term; import org.apache.cassandra.io.util.DataOutputBuffer; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.ByteBufferUtil; /* @@ -62,7 +63,7 @@ public class CompositeType extends AbstractCompositeType // interning instances private static final Map>, CompositeType> instances = new HashMap>, CompositeType>(); - public static CompositeType getInstance(TypeParser parser) throws ConfigurationException + public static CompositeType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { return getInstance(parser.getTypeParameters()); } diff --git a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java index 5eeccfdc87..36a3ee2886 100644 --- a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java +++ b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java @@ -22,7 +22,8 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; /* @@ -51,7 +52,7 @@ public class DynamicCompositeType extends AbstractCompositeType // interning instances private static final Map>, DynamicCompositeType> instances = new HashMap>, DynamicCompositeType>(); - public static synchronized DynamicCompositeType getInstance(TypeParser parser) throws ConfigurationException + public static synchronized DynamicCompositeType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { return getInstance(parser.getAliasParameters()); } @@ -95,6 +96,10 @@ public class DynamicCompositeType extends AbstractCompositeType { throw new RuntimeException(e); } + catch (SyntaxException e) + { + throw new RuntimeException(e); + } } protected AbstractType getComparator(int i, ByteBuffer bb) @@ -155,6 +160,10 @@ public class DynamicCompositeType extends AbstractCompositeType { throw new RuntimeException(e); } + catch (SyntaxException e) + { + throw new RuntimeException(e); + } } protected ParsedComparator parseComparator(int i, String part) @@ -259,6 +268,10 @@ public class DynamicCompositeType extends AbstractCompositeType } type = t; } + catch (SyntaxException e) + { + throw new IllegalArgumentException(e); + } catch (ConfigurationException e) { throw new IllegalArgumentException(e); diff --git a/src/java/org/apache/cassandra/db/marshal/ListType.java b/src/java/org/apache/cassandra/db/marshal/ListType.java index f18fc00459..c7b68170a1 100644 --- a/src/java/org/apache/cassandra/db/marshal/ListType.java +++ b/src/java/org/apache/cassandra/db/marshal/ListType.java @@ -21,7 +21,8 @@ import java.nio.ByteBuffer; import java.util.*; import org.apache.cassandra.db.IColumn; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -33,7 +34,7 @@ public class ListType extends CollectionType> public final AbstractType elements; - public static ListType getInstance(TypeParser parser) throws ConfigurationException + public static ListType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { List> l = parser.getTypeParameters(); if (l.size() != 1) diff --git a/src/java/org/apache/cassandra/db/marshal/MapType.java b/src/java/org/apache/cassandra/db/marshal/MapType.java index 2ac65cfc28..54c130e866 100644 --- a/src/java/org/apache/cassandra/db/marshal/MapType.java +++ b/src/java/org/apache/cassandra/db/marshal/MapType.java @@ -21,7 +21,8 @@ import java.nio.ByteBuffer; import java.util.*; import org.apache.cassandra.db.IColumn; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -34,7 +35,7 @@ public class MapType extends CollectionType> public final AbstractType keys; public final AbstractType values; - public static MapType getInstance(TypeParser parser) throws ConfigurationException + public static MapType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { List> l = parser.getTypeParameters(); if (l.size() != 2) diff --git a/src/java/org/apache/cassandra/db/marshal/ReversedType.java b/src/java/org/apache/cassandra/db/marshal/ReversedType.java index 131b97840b..d5db1e79a5 100644 --- a/src/java/org/apache/cassandra/db/marshal/ReversedType.java +++ b/src/java/org/apache/cassandra/db/marshal/ReversedType.java @@ -22,7 +22,8 @@ import java.util.HashMap; import java.util.Map; import java.util.List; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; public class ReversedType extends AbstractType { @@ -32,7 +33,7 @@ public class ReversedType extends AbstractType // package protected for unit tests sake final AbstractType baseType; - public static ReversedType getInstance(TypeParser parser) throws ConfigurationException + public static ReversedType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { List> types = parser.getTypeParameters(); if (types.size() != 1) diff --git a/src/java/org/apache/cassandra/db/marshal/SetType.java b/src/java/org/apache/cassandra/db/marshal/SetType.java index 7c71bafdfb..45b6e54c35 100644 --- a/src/java/org/apache/cassandra/db/marshal/SetType.java +++ b/src/java/org/apache/cassandra/db/marshal/SetType.java @@ -21,7 +21,8 @@ import java.nio.ByteBuffer; import java.util.*; import org.apache.cassandra.db.IColumn; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -33,7 +34,7 @@ public class SetType extends CollectionType> public final AbstractType elements; - public static SetType getInstance(TypeParser parser) throws ConfigurationException + public static SetType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException { List> l = parser.getTypeParameters(); if (l.size() != 1) diff --git a/src/java/org/apache/cassandra/db/marshal/TypeParser.java b/src/java/org/apache/cassandra/db/marshal/TypeParser.java index 538063884c..5813250fd2 100644 --- a/src/java/org/apache/cassandra/db/marshal/TypeParser.java +++ b/src/java/org/apache/cassandra/db/marshal/TypeParser.java @@ -29,7 +29,7 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; @@ -60,7 +60,7 @@ public class TypeParser /** * Parse a string containing an type definition. */ - public static AbstractType parse(String str) throws ConfigurationException + public static AbstractType parse(String str) throws SyntaxException, ConfigurationException { if (str == null) return BytesType.instance; @@ -93,7 +93,7 @@ public class TypeParser return type; } - public static AbstractType parse(CharSequence compareWith) throws ConfigurationException + public static AbstractType parse(CharSequence compareWith) throws SyntaxException, ConfigurationException { return parse(compareWith == null ? null : compareWith.toString()); } @@ -106,7 +106,7 @@ public class TypeParser /** * Parse an AbstractType from current position of this parser. */ - public AbstractType parse() throws ConfigurationException + public AbstractType parse() throws SyntaxException, ConfigurationException { skipBlank(); String name = readNextIdentifier(); @@ -118,7 +118,7 @@ public class TypeParser return getAbstractType(name); } - public Map getKeyValueParameters() throws ConfigurationException + public Map getKeyValueParameters() throws SyntaxException { Map map = new HashMap(); @@ -153,10 +153,10 @@ public class TypeParser } map.put(k, v); } - throw new ConfigurationException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); } - public List> getTypeParameters() throws ConfigurationException + public List> getTypeParameters() throws SyntaxException, ConfigurationException { List> list = new ArrayList>(); @@ -180,17 +180,17 @@ public class TypeParser { list.add(parse()); } - catch (ConfigurationException e) + catch (SyntaxException e) { - ConfigurationException ex = new ConfigurationException(String.format("Exception while parsing '%s' around char %d", str, idx)); + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", str, idx)); ex.initCause(e); throw ex; } } - throw new ConfigurationException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); } - public Map> getAliasParameters() throws ConfigurationException + public Map> getAliasParameters() throws SyntaxException, ConfigurationException { Map> map = new HashMap>(); @@ -228,17 +228,17 @@ public class TypeParser { map.put((byte)aliasChar, parse()); } - catch (ConfigurationException e) + catch (SyntaxException e) { - ConfigurationException ex = new ConfigurationException(String.format("Exception while parsing '%s' around char %d", str, idx)); + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", str, idx)); ex.initCause(e); throw ex; } } - throw new ConfigurationException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); } - public Map getCollectionsParameters() throws ConfigurationException + public Map getCollectionsParameters() throws SyntaxException, ConfigurationException { Map map = new HashMap(); @@ -279,17 +279,17 @@ public class TypeParser { AbstractType type = parse(); if (!(type instanceof CollectionType)) - throw new ConfigurationException(type.toString() + " is not a collection type"); + throw new SyntaxException(type.toString() + " is not a collection type"); map.put(bb, (CollectionType)type); } - catch (ConfigurationException e) + catch (SyntaxException e) { - ConfigurationException ex = new ConfigurationException(String.format("Exception while parsing '%s' around char %d", str, idx)); + SyntaxException ex = new SyntaxException(String.format("Exception while parsing '%s' around char %d", str, idx)); ex.initCause(e); throw ex; } } - throw new ConfigurationException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: unexpected end of string", str, idx)); } private static AbstractType getAbstractType(String compareWith) throws ConfigurationException @@ -313,7 +313,7 @@ public class TypeParser } } - private static AbstractType getAbstractType(String compareWith, TypeParser parser) throws ConfigurationException + private static AbstractType getAbstractType(String compareWith, TypeParser parser) throws SyntaxException, ConfigurationException { String className = compareWith.contains(".") ? compareWith : "org.apache.cassandra.db.marshal." + compareWith; Class> typeClass = FBUtilities.>classForName(className, "abstract-type"); @@ -382,9 +382,9 @@ public class TypeParser } } - private void throwSyntaxError(String msg) throws ConfigurationException + private void throwSyntaxError(String msg) throws SyntaxException { - throw new ConfigurationException(String.format("Syntax error parsing '%s' at char %d: %s", str, idx, msg)); + throw new SyntaxException(String.format("Syntax error parsing '%s' at char %d: %s", str, idx, msg)); } private boolean isEOS() diff --git a/src/java/org/apache/cassandra/dht/AbstractByteOrderedPartitioner.java b/src/java/org/apache/cassandra/dht/AbstractByteOrderedPartitioner.java index 36a51733f4..cff4754038 100644 --- a/src/java/org/apache/cassandra/dht/AbstractByteOrderedPartitioner.java +++ b/src/java/org/apache/cassandra/dht/AbstractByteOrderedPartitioner.java @@ -26,6 +26,7 @@ import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.commons.lang.ArrayUtils; import org.apache.cassandra.db.DecoratedKey; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Hex; diff --git a/src/java/org/apache/cassandra/dht/BootStrapper.java b/src/java/org/apache/cassandra/dht/BootStrapper.java index 1942be8da5..d6c0fc2016 100644 --- a/src/java/org/apache/cassandra/dht/BootStrapper.java +++ b/src/java/org/apache/cassandra/dht/BootStrapper.java @@ -28,9 +28,8 @@ import java.util.concurrent.locks.Condition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.Schema; -import org.apache.cassandra.gms.*; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.Table; import org.apache.cassandra.locator.AbstractReplicationStrategy; diff --git a/src/java/org/apache/cassandra/dht/Murmur3Partitioner.java b/src/java/org/apache/cassandra/dht/Murmur3Partitioner.java index fb8d7212f6..3a3972b6ce 100644 --- a/src/java/org/apache/cassandra/dht/Murmur3Partitioner.java +++ b/src/java/org/apache/cassandra/dht/Murmur3Partitioner.java @@ -24,8 +24,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.DecoratedKey; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.MurmurHash; diff --git a/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java b/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java index f0a83f3c46..25f26f4438 100644 --- a/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java +++ b/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java @@ -24,6 +24,7 @@ import java.util.*; import org.apache.cassandra.config.*; import org.apache.cassandra.db.DecoratedKey; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.VersionedValue; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.ByteBufferUtil; diff --git a/src/java/org/apache/cassandra/dht/RandomPartitioner.java b/src/java/org/apache/cassandra/dht/RandomPartitioner.java index cf3855bd94..da11fd1b93 100644 --- a/src/java/org/apache/cassandra/dht/RandomPartitioner.java +++ b/src/java/org/apache/cassandra/dht/RandomPartitioner.java @@ -23,7 +23,7 @@ import java.nio.ByteBuffer; import java.nio.charset.CharacterCodingException; import java.util.*; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/dht/Token.java b/src/java/org/apache/cassandra/dht/Token.java index 2aeafbd534..d392972c9b 100644 --- a/src/java/org/apache/cassandra/dht/Token.java +++ b/src/java/org/apache/cassandra/dht/Token.java @@ -23,7 +23,7 @@ import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.TypeSizes; import org.apache.cassandra.db.RowPosition; import org.apache.cassandra.io.ISerializer; diff --git a/src/java/org/apache/cassandra/exceptions/AlreadyExistsException.java b/src/java/org/apache/cassandra/exceptions/AlreadyExistsException.java new file mode 100644 index 0000000000..f023a0774c --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/AlreadyExistsException.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.exceptions; + +public class AlreadyExistsException extends ConfigurationException +{ + public final String ksName; + public final String cfName; + + private AlreadyExistsException(String ksName, String cfName, String msg) + { + super(ExceptionCode.ALREADY_EXISTS, msg); + this.ksName = ksName; + this.cfName = cfName; + } + + public AlreadyExistsException(String ksName, String cfName) + { + this(ksName, cfName, String.format("Cannot add already existing column family \"%s\" to keyspace \"%s\"", ksName, cfName)); + } + + public AlreadyExistsException(String ksName) + { + this(ksName, "", String.format("Cannot add existing keyspace \"%s\"", ksName)); + } + +} diff --git a/src/java/org/apache/cassandra/exceptions/CassandraException.java b/src/java/org/apache/cassandra/exceptions/CassandraException.java new file mode 100644 index 0000000000..00790d6fee --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/CassandraException.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.exceptions; + +import java.nio.ByteBuffer; + +public abstract class CassandraException extends Exception implements TransportException +{ + private final ExceptionCode code; + + protected CassandraException(ExceptionCode code, String msg) + { + super(msg); + this.code = code; + } + + protected CassandraException(ExceptionCode code, String msg, Throwable cause) + { + super(msg, cause); + this.code = code; + } + + public ExceptionCode code() + { + return code; + } +} diff --git a/src/java/org/apache/cassandra/exceptions/ConfigurationException.java b/src/java/org/apache/cassandra/exceptions/ConfigurationException.java new file mode 100644 index 0000000000..8f0bb1af67 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/ConfigurationException.java @@ -0,0 +1,36 @@ +/* + * 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.exceptions; + +public class ConfigurationException extends RequestValidationException +{ + public ConfigurationException(String msg) + { + super(ExceptionCode.CONFIG_ERROR, msg); + } + + public ConfigurationException(String msg, Throwable e) + { + super(ExceptionCode.CONFIG_ERROR, msg, e); + } + + protected ConfigurationException(ExceptionCode code, String msg) + { + super(code, msg); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/ExceptionCode.java b/src/java/org/apache/cassandra/exceptions/ExceptionCode.java new file mode 100644 index 0000000000..13fcc6af49 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/ExceptionCode.java @@ -0,0 +1,68 @@ +/* + * 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.exceptions; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.cassandra.transport.ProtocolException; + +/** + * Exceptions code, as defined by the binary protocol. + */ +public enum ExceptionCode +{ + SERVER_ERROR (0x0000), + PROTOCOL_ERROR (0x000A), + + // 1xx: problem during request execution + UNAVAILABLE (0x1000), + OVERLOADED (0x1001), + IS_BOOTSTRAPPING(0x1002), + TRUNCATE_ERROR (0x1003), + WRITE_TIMEOUT (0x1100), + READ_TIMEOUT (0x1200), + + // 2xx: problem validating the request + SYNTAX_ERROR (0x2000), + UNAUTHORIZED (0x2100), + INVALID (0x2200), + CONFIG_ERROR (0x2300), + ALREADY_EXISTS (0x2400); + + public final int value; + private static final Map valueToCode = new HashMap(ExceptionCode.values().length); + static + { + for (ExceptionCode code : ExceptionCode.values()) + valueToCode.put(code.value, code); + } + + private ExceptionCode(int value) + { + this.value = value; + } + + public static ExceptionCode fromValue(int value) + { + ExceptionCode code = valueToCode.get(value); + if (code == null) + throw new ProtocolException(String.format("Unknown error code %d", value)); + return code; + } +} diff --git a/src/java/org/apache/cassandra/config/ConfigurationException.java b/src/java/org/apache/cassandra/exceptions/InvalidRequestException.java similarity index 75% rename from src/java/org/apache/cassandra/config/ConfigurationException.java rename to src/java/org/apache/cassandra/exceptions/InvalidRequestException.java index c23a52271c..4259d1a218 100644 --- a/src/java/org/apache/cassandra/config/ConfigurationException.java +++ b/src/java/org/apache/cassandra/exceptions/InvalidRequestException.java @@ -15,17 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.cassandra.config; +package org.apache.cassandra.exceptions; -public class ConfigurationException extends Exception +public class InvalidRequestException extends RequestValidationException { - public ConfigurationException(String message) + public InvalidRequestException(String msg) { - super(message); - } - - public ConfigurationException(String message, Exception e) - { - super(message, e); + super(ExceptionCode.INVALID, msg); } } diff --git a/src/java/org/apache/cassandra/exceptions/IsBootstrappingException.java b/src/java/org/apache/cassandra/exceptions/IsBootstrappingException.java new file mode 100644 index 0000000000..b25a3184d7 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/IsBootstrappingException.java @@ -0,0 +1,26 @@ +/* + * 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.exceptions; + +public class IsBootstrappingException extends RequestExecutionException +{ + public IsBootstrappingException() + { + super(ExceptionCode.IS_BOOTSTRAPPING, "Cannot read from a bootstrapping node"); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/OverloadedException.java b/src/java/org/apache/cassandra/exceptions/OverloadedException.java new file mode 100644 index 0000000000..0235a535c4 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/OverloadedException.java @@ -0,0 +1,26 @@ +/* + * 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.exceptions; + +public class OverloadedException extends RequestExecutionException +{ + public OverloadedException(String reason) + { + super(ExceptionCode.OVERLOADED, reason); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/ReadTimeoutException.java b/src/java/org/apache/cassandra/exceptions/ReadTimeoutException.java new file mode 100644 index 0000000000..3af638dddb --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/ReadTimeoutException.java @@ -0,0 +1,36 @@ +/* + * 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.exceptions; + +import java.net.InetAddress; +import java.util.Set; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.utils.ByteBufferUtil; + +public class ReadTimeoutException extends RequestTimeoutException +{ + public final boolean dataPresent; + + public ReadTimeoutException(ConsistencyLevel consistency, int received, int blockFor, boolean dataPresent) + { + super(ExceptionCode.READ_TIMEOUT, consistency, received, blockFor); + this.dataPresent = dataPresent; + } +} diff --git a/src/java/org/apache/cassandra/exceptions/RequestExecutionException.java b/src/java/org/apache/cassandra/exceptions/RequestExecutionException.java new file mode 100644 index 0000000000..8d9839fb13 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/RequestExecutionException.java @@ -0,0 +1,33 @@ +/* + * 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.exceptions; + +import org.apache.cassandra.db.ConsistencyLevel; + +public abstract class RequestExecutionException extends CassandraException +{ + protected RequestExecutionException(ExceptionCode code, String msg) + { + super(code, msg); + } + + protected RequestExecutionException(ExceptionCode code, String msg, Throwable e) + { + super(code, msg, e); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/RequestTimeoutException.java b/src/java/org/apache/cassandra/exceptions/RequestTimeoutException.java new file mode 100644 index 0000000000..b6cfb86027 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/RequestTimeoutException.java @@ -0,0 +1,40 @@ +/* + * 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.exceptions; + +import java.net.InetAddress; +import java.util.Set; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.utils.ByteBufferUtil; + +public class RequestTimeoutException extends RequestExecutionException +{ + public final ConsistencyLevel consistency; + public final int received; + public final int blockFor; + + protected RequestTimeoutException(ExceptionCode code, ConsistencyLevel consistency, int received, int blockFor) + { + super(code, String.format("Operation timed out - received only %d responses.", received)); + this.consistency = consistency; + this.received = received; + this.blockFor = blockFor; + } +} diff --git a/src/java/org/apache/cassandra/exceptions/RequestValidationException.java b/src/java/org/apache/cassandra/exceptions/RequestValidationException.java new file mode 100644 index 0000000000..a168274067 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/RequestValidationException.java @@ -0,0 +1,31 @@ +/* + * 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.exceptions; + +public abstract class RequestValidationException extends CassandraException +{ + protected RequestValidationException(ExceptionCode code, String msg) + { + super(code, msg); + } + + protected RequestValidationException(ExceptionCode code, String msg, Throwable e) + { + super(code, msg, e); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/SyntaxException.java b/src/java/org/apache/cassandra/exceptions/SyntaxException.java new file mode 100644 index 0000000000..3a3db35c75 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/SyntaxException.java @@ -0,0 +1,26 @@ +/* + * 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.exceptions; + +public class SyntaxException extends RequestValidationException +{ + public SyntaxException(String msg) + { + super(ExceptionCode.SYNTAX_ERROR, msg); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/TransportException.java b/src/java/org/apache/cassandra/exceptions/TransportException.java new file mode 100644 index 0000000000..940f723eb9 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/TransportException.java @@ -0,0 +1,33 @@ +/* + * 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.exceptions; + +import java.nio.ByteBuffer; + +public interface TransportException +{ + /** + * The exception code. + */ + public ExceptionCode code(); + + /** + * The exception message. + */ + public String getMessage(); +} diff --git a/src/java/org/apache/cassandra/exceptions/TruncateException.java b/src/java/org/apache/cassandra/exceptions/TruncateException.java new file mode 100644 index 0000000000..6d6e0272da --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/TruncateException.java @@ -0,0 +1,31 @@ +/* + * 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.exceptions; + +public class TruncateException extends RequestExecutionException +{ + public TruncateException(Throwable e) + { + super(ExceptionCode.TRUNCATE_ERROR, "Error during truncate: " + e.getMessage(), e); + } + + public TruncateException(String msg) + { + super(ExceptionCode.TRUNCATE_ERROR, msg); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/UnauthorizedException.java b/src/java/org/apache/cassandra/exceptions/UnauthorizedException.java new file mode 100644 index 0000000000..12a3f8af67 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/UnauthorizedException.java @@ -0,0 +1,26 @@ +/* + * 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.exceptions; + +public class UnauthorizedException extends RequestValidationException +{ + public UnauthorizedException(String msg) + { + super(ExceptionCode.UNAUTHORIZED, msg); + } +} diff --git a/src/java/org/apache/cassandra/exceptions/UnavailableException.java b/src/java/org/apache/cassandra/exceptions/UnavailableException.java new file mode 100644 index 0000000000..ceb87d8a46 --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/UnavailableException.java @@ -0,0 +1,40 @@ +/* + * 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.exceptions; + +import java.net.InetAddress; +import java.util.Collection; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.utils.ByteBufferUtil; + +public class UnavailableException extends RequestExecutionException +{ + public final ConsistencyLevel consistency; + public final int required; + public final int alive; + + public UnavailableException(ConsistencyLevel consistency, int required, int alive) + { + super(ExceptionCode.UNAVAILABLE, "Cannot achieve consistency level " + consistency); + this.consistency = consistency; + this.required = required; + this.alive = alive; + } +} diff --git a/src/java/org/apache/cassandra/exceptions/WriteTimeoutException.java b/src/java/org/apache/cassandra/exceptions/WriteTimeoutException.java new file mode 100644 index 0000000000..607215b21e --- /dev/null +++ b/src/java/org/apache/cassandra/exceptions/WriteTimeoutException.java @@ -0,0 +1,32 @@ +/* + * 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.exceptions; + +import java.net.InetAddress; +import java.util.Set; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.ConsistencyLevel; + +public class WriteTimeoutException extends RequestTimeoutException +{ + public WriteTimeoutException(ConsistencyLevel consistency, int received, int blockFor) + { + super(ExceptionCode.WRITE_TIMEOUT, consistency, received, blockFor); + } +} diff --git a/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java b/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java index db284ecd37..3385b35679 100644 --- a/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java +++ b/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java @@ -31,7 +31,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.auth.IAuthenticator; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.IColumn; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.TypeParser; diff --git a/src/java/org/apache/cassandra/hadoop/ConfigHelper.java b/src/java/org/apache/cassandra/hadoop/ConfigHelper.java index 1374162e42..0c390cc3ad 100644 --- a/src/java/org/apache/cassandra/hadoop/ConfigHelper.java +++ b/src/java/org/apache/cassandra/hadoop/ConfigHelper.java @@ -30,7 +30,7 @@ import org.apache.cassandra.io.compress.CompressionParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.thrift.*; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/hadoop/pig/CassandraStorage.java b/src/java/org/apache/cassandra/hadoop/pig/CassandraStorage.java index 33bddfe3f4..c0c299701d 100644 --- a/src/java/org/apache/cassandra/hadoop/pig/CassandraStorage.java +++ b/src/java/org/apache/cassandra/hadoop/pig/CassandraStorage.java @@ -22,11 +22,12 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.*; -import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.BytesType; import org.apache.cassandra.db.marshal.IntegerType; import org.apache.cassandra.db.marshal.TypeParser; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.thrift.*; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Hex; @@ -402,6 +403,10 @@ public class CassandraStorage extends LoadFunc implements StoreFuncInterface, Lo { throw new IOException(e); } + catch (SyntaxException e) + { + throw new IOException(e); + } } } return validators; @@ -420,6 +425,10 @@ public class CassandraStorage extends LoadFunc implements StoreFuncInterface, Lo { throw new IOException(e); } + catch (SyntaxException e) + { + throw new IOException(e); + } } @Override diff --git a/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java b/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java index a68de8a15c..5587efc6b1 100644 --- a/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java +++ b/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java @@ -22,7 +22,7 @@ import java.util.*; import com.google.common.primitives.Longs; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.TypeSizes; import org.apache.cassandra.io.FSReadError; import org.apache.cassandra.io.FSWriteError; diff --git a/src/java/org/apache/cassandra/io/compress/CompressionParameters.java b/src/java/org/apache/cassandra/io/compress/CompressionParameters.java index 4ee7bef610..25fc742e7e 100644 --- a/src/java/org/apache/cassandra/io/compress/CompressionParameters.java +++ b/src/java/org/apache/cassandra/io/compress/CompressionParameters.java @@ -30,7 +30,7 @@ import java.util.Set; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.TypeSizes; import org.apache.cassandra.io.IVersionedSerializer; diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableLoader.java b/src/java/org/apache/cassandra/io/sstable/SSTableLoader.java index 49d3219cf4..13e2b99743 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableLoader.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableLoader.java @@ -28,7 +28,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.cassandra.config.Config; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Range; diff --git a/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java b/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java index 66fb849114..3b81ab828a 100644 --- a/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java +++ b/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java @@ -26,7 +26,7 @@ import com.google.common.collect.Multimap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.Range; import org.apache.cassandra.dht.RingPosition; import org.apache.cassandra.dht.Token; @@ -34,7 +34,7 @@ import org.apache.cassandra.service.DatacenterSyncWriteResponseHandler; import org.apache.cassandra.service.DatacenterWriteResponseHandler; import org.apache.cassandra.service.IWriteResponseHandler; import org.apache.cassandra.service.WriteResponseHandler; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.FBUtilities; import org.cliffc.high_scale_lib.NonBlockingHashMap; diff --git a/src/java/org/apache/cassandra/locator/Ec2MultiRegionSnitch.java b/src/java/org/apache/cassandra/locator/Ec2MultiRegionSnitch.java index 4c6ab32aab..e29637f8be 100644 --- a/src/java/org/apache/cassandra/locator/Ec2MultiRegionSnitch.java +++ b/src/java/org/apache/cassandra/locator/Ec2MultiRegionSnitch.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.EndpointState; diff --git a/src/java/org/apache/cassandra/locator/Ec2Snitch.java b/src/java/org/apache/cassandra/locator/Ec2Snitch.java index 729121d996..5485977592 100644 --- a/src/java/org/apache/cassandra/locator/Ec2Snitch.java +++ b/src/java/org/apache/cassandra/locator/Ec2Snitch.java @@ -28,7 +28,7 @@ import com.google.common.base.Charsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.EndpointState; import org.apache.cassandra.gms.Gossiper; diff --git a/src/java/org/apache/cassandra/locator/GossipingPropertyFileSnitch.java b/src/java/org/apache/cassandra/locator/GossipingPropertyFileSnitch.java index 9a22544eb8..adc8b2466a 100644 --- a/src/java/org/apache/cassandra/locator/GossipingPropertyFileSnitch.java +++ b/src/java/org/apache/cassandra/locator/GossipingPropertyFileSnitch.java @@ -18,7 +18,7 @@ package org.apache.cassandra.locator; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.EndpointState; import org.apache.cassandra.gms.Gossiper; diff --git a/src/java/org/apache/cassandra/locator/LocalStrategy.java b/src/java/org/apache/cassandra/locator/LocalStrategy.java index 09318de3d0..17ad181106 100644 --- a/src/java/org/apache/cassandra/locator/LocalStrategy.java +++ b/src/java/org/apache/cassandra/locator/LocalStrategy.java @@ -23,7 +23,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.RingPosition; import org.apache.cassandra.dht.Token; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java index 70868649db..8b251d7413 100644 --- a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java +++ b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java @@ -24,7 +24,7 @@ import java.util.Map.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.Token; import org.apache.cassandra.locator.TokenMetadata.Topology; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java b/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java index 4d8db9dbc9..f07328b8fd 100644 --- a/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java +++ b/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java @@ -23,7 +23,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.Token; /** diff --git a/src/java/org/apache/cassandra/locator/PropertyFileSnitch.java b/src/java/org/apache/cassandra/locator/PropertyFileSnitch.java index 675297ae95..1c25ca898a 100644 --- a/src/java/org/apache/cassandra/locator/PropertyFileSnitch.java +++ b/src/java/org/apache/cassandra/locator/PropertyFileSnitch.java @@ -27,7 +27,7 @@ import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.FBUtilities; diff --git a/src/java/org/apache/cassandra/locator/SimpleStrategy.java b/src/java/org/apache/cassandra/locator/SimpleStrategy.java index 50d470f264..7f2733488a 100644 --- a/src/java/org/apache/cassandra/locator/SimpleStrategy.java +++ b/src/java/org/apache/cassandra/locator/SimpleStrategy.java @@ -24,7 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.Token; diff --git a/src/java/org/apache/cassandra/net/MessagingService.java b/src/java/org/apache/cassandra/net/MessagingService.java index c4ceae2609..1a22273852 100644 --- a/src/java/org/apache/cassandra/net/MessagingService.java +++ b/src/java/org/apache/cassandra/net/MessagingService.java @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor; import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.db.*; diff --git a/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java b/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java index 4c1a83b44e..328e1ea197 100644 --- a/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java +++ b/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java @@ -22,10 +22,10 @@ import java.util.Collection; import java.util.concurrent.TimeUnit; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.exceptions.UnavailableException; +import org.apache.cassandra.exceptions.WriteTimeoutException; import org.apache.cassandra.net.MessageIn; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.SimpleCondition; public abstract class AbstractWriteResponseHandler implements IWriteResponseHandler @@ -42,7 +42,7 @@ public abstract class AbstractWriteResponseHandler implements IWriteResponseHand this.writeEndpoints = writeEndpoints; } - public void get() throws TimedOutException + public void get() throws WriteTimeoutException { long timeout = DatabaseDescriptor.getWriteRpcTimeout() - (System.currentTimeMillis() - startTime); @@ -57,13 +57,13 @@ public abstract class AbstractWriteResponseHandler implements IWriteResponseHand } if (!success) - { - throw new TimedOutException().setAcknowledged_by(ackCount()); - } + throw new WriteTimeoutException(consistencyLevel, ackCount(), blockFor()); } protected abstract int ackCount(); + protected abstract int blockFor(); + /** null message means "response from local write" */ public abstract void response(MessageIn msg); diff --git a/src/java/org/apache/cassandra/service/CassandraDaemon.java b/src/java/org/apache/cassandra/service/CassandraDaemon.java index 4e64fa36e2..773aa47254 100644 --- a/src/java/org/apache/cassandra/service/CassandraDaemon.java +++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java @@ -32,7 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.*; diff --git a/src/java/org/apache/cassandra/service/ClientState.java b/src/java/org/apache/cassandra/service/ClientState.java index a04f3f1d92..b85b359af8 100644 --- a/src/java/org/apache/cassandra/service/ClientState.java +++ b/src/java/org/apache/cassandra/service/ClientState.java @@ -30,8 +30,9 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.cql.CQLStatement; import org.apache.cassandra.db.Table; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.thrift.AuthenticationException; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.SemanticVersion; @@ -185,7 +186,7 @@ public class ClientState /** * Confirms that the client thread has the given Permission for the Keyspace list. */ - public void hasKeyspaceSchemaAccess(Permission perm) throws InvalidRequestException + public void hasKeyspaceSchemaAccess(Permission perm) throws UnauthorizedException, InvalidRequestException { validateLogin(); @@ -195,7 +196,7 @@ public class ClientState hasAccess(user, perms, perm, resource); } - public void hasColumnFamilySchemaAccess(Permission perm) throws InvalidRequestException + public void hasColumnFamilySchemaAccess(Permission perm) throws UnauthorizedException, InvalidRequestException { hasColumnFamilySchemaAccess(keyspace, perm); } @@ -204,14 +205,14 @@ public class ClientState * Confirms that the client thread has the given Permission for the ColumnFamily list of * the provided keyspace. */ - public void hasColumnFamilySchemaAccess(String keyspace, Permission perm) throws InvalidRequestException + public void hasColumnFamilySchemaAccess(String keyspace, Permission perm) throws UnauthorizedException, InvalidRequestException { validateLogin(); validateKeyspace(keyspace); // hardcode disallowing messing with system keyspace if (keyspace.equalsIgnoreCase(Table.SYSTEM_KS) && perm == Permission.WRITE) - throw new InvalidRequestException("system keyspace is not user-modifiable"); + throw new UnauthorizedException("system keyspace is not user-modifiable"); resourceClear(); resource.add(keyspace); @@ -224,12 +225,12 @@ public class ClientState * Confirms that the client thread has the given Permission in the context of the given * ColumnFamily and the current keyspace. */ - public void hasColumnFamilyAccess(String columnFamily, Permission perm) throws InvalidRequestException + public void hasColumnFamilyAccess(String columnFamily, Permission perm) throws UnauthorizedException, InvalidRequestException { hasColumnFamilyAccess(keyspace, columnFamily, perm); } - public void hasColumnFamilyAccess(String keyspace, String columnFamily, Permission perm) throws InvalidRequestException + public void hasColumnFamilyAccess(String keyspace, String columnFamily, Permission perm) throws UnauthorizedException, InvalidRequestException { validateLogin(); validateKeyspace(keyspace); @@ -259,14 +260,14 @@ public class ClientState throw new InvalidRequestException("You have not set a keyspace for this session"); } - private static void hasAccess(AuthenticatedUser user, Set perms, Permission perm, List resource) throws InvalidRequestException + private static void hasAccess(AuthenticatedUser user, Set perms, Permission perm, List resource) throws UnauthorizedException { if (perms.contains(perm)) return; - throw new InvalidRequestException(String.format("%s does not have permission %s for %s", - user, - perm, - Resources.toString(resource))); + throw new UnauthorizedException(String.format("%s does not have permission %s for %s", + user, + perm, + Resources.toString(resource))); } /** diff --git a/src/java/org/apache/cassandra/service/DatacenterReadCallback.java b/src/java/org/apache/cassandra/service/DatacenterReadCallback.java index 76d6f01ad7..84e0c590a2 100644 --- a/src/java/org/apache/cassandra/service/DatacenterReadCallback.java +++ b/src/java/org/apache/cassandra/service/DatacenterReadCallback.java @@ -22,12 +22,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.ReadResponse; import org.apache.cassandra.db.Table; +import org.apache.cassandra.exceptions.UnavailableException; import org.apache.cassandra.locator.NetworkTopologyStrategy; import org.apache.cassandra.net.MessageIn; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.thrift.protocol.TMessage; /** @@ -66,13 +66,6 @@ public class DatacenterReadCallback extends ReadCallback extends ReadCallback responses = new HashMap(); @@ -55,6 +56,7 @@ public class DatacenterSyncWriteResponseHandler extends AbstractWriteResponseHan super(writeEndpoints, consistencyLevel); assert consistencyLevel == ConsistencyLevel.EACH_QUORUM; + this.table = table; strategy = (NetworkTopologyStrategy) Table.open(table).getReplicationStrategy(); for (String dc : strategy.getDatacenters()) @@ -87,6 +89,11 @@ public class DatacenterSyncWriteResponseHandler extends AbstractWriteResponseHan condition.signal(); } + protected int blockFor() + { + return consistencyLevel.blockFor(table); + } + protected int ackCount() { int n = 0; @@ -119,7 +126,7 @@ public class DatacenterSyncWriteResponseHandler extends AbstractWriteResponseHan for (String dc: strategy.getDatacenters()) { if (dcEndpoints.get(dc).get() < responses.get(dc).get()) - throw new UnavailableException(); + throw new UnavailableException(consistencyLevel, responses.get(dc).get(), dcEndpoints.get(dc).get()); } } diff --git a/src/java/org/apache/cassandra/service/DatacenterWriteResponseHandler.java b/src/java/org/apache/cassandra/service/DatacenterWriteResponseHandler.java index 7592ad2c1c..6644b1ac66 100644 --- a/src/java/org/apache/cassandra/service/DatacenterWriteResponseHandler.java +++ b/src/java/org/apache/cassandra/service/DatacenterWriteResponseHandler.java @@ -22,12 +22,12 @@ import java.util.Collection; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.Table; +import org.apache.cassandra.exceptions.UnavailableException; import org.apache.cassandra.gms.FailureDetector; import org.apache.cassandra.locator.IEndpointSnitch; import org.apache.cassandra.locator.NetworkTopologyStrategy; import org.apache.cassandra.net.MessageIn; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.FBUtilities; /** @@ -54,14 +54,6 @@ public class DatacenterWriteResponseHandler extends WriteResponseHandler return new DatacenterWriteResponseHandler(writeEndpoints, consistencyLevel, table); } - @Override - protected int determineBlockFor(String table) - { - NetworkTopologyStrategy strategy = (NetworkTopologyStrategy) Table.open(table).getReplicationStrategy(); - return (strategy.getReplicationFactor(localdc) / 2) + 1; - } - - @Override public void response(MessageIn message) { @@ -84,7 +76,7 @@ public class DatacenterWriteResponseHandler extends WriteResponseHandler if (liveNodes < responses.get()) { - throw new UnavailableException(); + throw new UnavailableException(consistencyLevel, responses.get(), liveNodes); } } diff --git a/src/java/org/apache/cassandra/service/IWriteResponseHandler.java b/src/java/org/apache/cassandra/service/IWriteResponseHandler.java index 0127ecdd86..aa776359f6 100644 --- a/src/java/org/apache/cassandra/service/IWriteResponseHandler.java +++ b/src/java/org/apache/cassandra/service/IWriteResponseHandler.java @@ -18,11 +18,11 @@ package org.apache.cassandra.service; import org.apache.cassandra.net.IAsyncCallback; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.exceptions.WriteTimeoutException; +import org.apache.cassandra.exceptions.UnavailableException; public interface IWriteResponseHandler extends IAsyncCallback { - public void get() throws TimedOutException; + public void get() throws WriteTimeoutException; public void assureSufficientLiveNodes() throws UnavailableException; } diff --git a/src/java/org/apache/cassandra/service/MigrationManager.java b/src/java/org/apache/cassandra/service/MigrationManager.java index a31cbbca21..f7ba70194c 100644 --- a/src/java/org/apache/cassandra/service/MigrationManager.java +++ b/src/java/org/apache/cassandra/service/MigrationManager.java @@ -34,7 +34,8 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.AlreadyExistsException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.KSMetaData; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.*; @@ -111,7 +112,7 @@ public class MigrationManager implements IEndpointStateChangeSubscriber ksm.validate(); if (Schema.instance.getTableDefinition(ksm.name) != null) - throw new ConfigurationException(String.format("Cannot add already existing keyspace '%s'.", ksm.name)); + throw new AlreadyExistsException(ksm.name); logger.info(String.format("Create new Keyspace: %s", ksm)); announce(ksm.toSchema(FBUtilities.timestampMicros())); @@ -125,7 +126,7 @@ public class MigrationManager implements IEndpointStateChangeSubscriber if (ksm == null) throw new ConfigurationException(String.format("Cannot add column family '%s' to non existing keyspace '%s'.", cfm.cfName, cfm.ksName)); else if (ksm.cfMetaData().containsKey(cfm.cfName)) - throw new ConfigurationException(String.format("Cannot add already existing column family '%s' to keyspace '%s'.", cfm.cfName, cfm.ksName)); + throw new AlreadyExistsException(cfm.cfName, cfm.ksName); logger.info(String.format("Create new ColumnFamily: %s", cfm)); announce(cfm.toSchema(FBUtilities.timestampMicros())); diff --git a/src/java/org/apache/cassandra/service/MigrationTask.java b/src/java/org/apache/cassandra/service/MigrationTask.java index 70b917d850..ac7c6bed20 100644 --- a/src/java/org/apache/cassandra/service/MigrationTask.java +++ b/src/java/org/apache/cassandra/service/MigrationTask.java @@ -24,7 +24,7 @@ import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.DefsTable; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.gms.FailureDetector; diff --git a/src/java/org/apache/cassandra/service/ReadCallback.java b/src/java/org/apache/cassandra/service/ReadCallback.java index bfd0044c4b..f6cf0bd901 100644 --- a/src/java/org/apache/cassandra/service/ReadCallback.java +++ b/src/java/org/apache/cassandra/service/ReadCallback.java @@ -21,8 +21,8 @@ import java.io.IOException; import java.net.InetAddress; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import org.apache.cassandra.config.Schema; @@ -37,13 +37,14 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.ReadCommand; import org.apache.cassandra.db.ReadResponse; import org.apache.cassandra.db.Table; +import org.apache.cassandra.exceptions.ReadTimeoutException; +import org.apache.cassandra.exceptions.UnavailableException; import org.apache.cassandra.locator.IEndpointSnitch; import org.apache.cassandra.net.IAsyncCallback; import org.apache.cassandra.net.MessageIn; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.SimpleCondition; import org.apache.cassandra.utils.WrappedRunnable; @@ -63,6 +64,7 @@ public class ReadCallback implements IAsyncCallback endpoints; private final IReadCommand command; + protected final ConsistencyLevel consistencyLevel; protected final AtomicInteger received = new AtomicInteger(0); /** @@ -71,9 +73,10 @@ public class ReadCallback implements IAsyncCallback resolver, ConsistencyLevel consistencyLevel, IReadCommand command, List endpoints) { this.command = command; - this.blockfor = determineBlockFor(consistencyLevel, command.getKeyspace()); + this.blockfor = consistencyLevel.blockFor(command.getKeyspace()); this.resolver = resolver; this.startTime = System.currentTimeMillis(); + this.consistencyLevel = consistencyLevel; sortForConsistencyLevel(endpoints); this.endpoints = resolver instanceof RowRepairResolver ? endpoints : filterEndpoints(endpoints); if (logger.isDebugEnabled()) @@ -127,7 +130,7 @@ public class ReadCallback implements IAsyncCallback implements IAsyncCallback implements IAsyncCallback mutations, ConsistencyLevel consistency_level) throws UnavailableException, TimedOutException + public static void mutate(List mutations, ConsistencyLevel consistency_level) + throws UnavailableException, OverloadedException, WriteTimeoutException { logger.debug("Mutations/ConsistencyLevel are {}/{}", mutations, consistency_level); final String localDataCenter = DatabaseDescriptor.getEndpointSnitch().getDatacenter(FBUtilities.getBroadcastAddress()); @@ -195,7 +197,7 @@ public class StorageProxy implements StorageProxyMBean } } - catch (TimedOutException ex) + catch (WriteTimeoutException ex) { writeMetrics.timeouts.mark(); ClientRequestMetrics.writeTimeouts.inc(); @@ -204,7 +206,7 @@ public class StorageProxy implements StorageProxyMBean List mstrings = new ArrayList(mutations.size()); for (IMutation mutation : mutations) mstrings.add(mutation.toString(true)); - logger.debug("Write timeout {} for one (or more) of: ", ex.toString(), mstrings); + logger.debug("Write timeout {} for one (or more) of: {}", ex.toString(), mstrings); } throw ex; } @@ -214,6 +216,11 @@ public class StorageProxy implements StorageProxyMBean ClientRequestMetrics.writeUnavailables.inc(); throw e; } + catch (OverloadedException e) + { + ClientRequestMetrics.writeUnavailables.inc(); + throw e; + } catch (IOException e) { assert mostRecentMutation != null; @@ -241,7 +248,7 @@ public class StorageProxy implements StorageProxyMBean ConsistencyLevel consistency_level, String localDataCenter, WritePerformer performer) - throws UnavailableException, IOException + throws UnavailableException, OverloadedException, IOException { String table = mutation.getTable(); AbstractReplicationStrategy rs = Table.open(table).getReplicationStrategy(); @@ -284,7 +291,7 @@ public class StorageProxy implements StorageProxyMBean IWriteResponseHandler responseHandler, String localDataCenter, ConsistencyLevel consistency_level) - throws IOException, UnavailableException + throws IOException, OverloadedException { // Multimap that holds onto all the messages and addresses meant for a specific datacenter Map> dcMessages = new HashMap>(targets.size()); @@ -299,7 +306,7 @@ public class StorageProxy implements StorageProxyMBean if (totalHintsInProgress.get() > maxHintsInProgress && (hintsInProgress.get(destination).get() > 0 && shouldHint(destination))) { - throw new UnavailableException(); + throw new OverloadedException("Too many in flight hints: " + totalHintsInProgress.get()); } if (FailureDetector.instance.isAlive(destination)) @@ -470,9 +477,9 @@ public class StorageProxy implements StorageProxyMBean * quicker response and because the WriteResponseHandlers don't make it easy to send back an error. We also always gather * the write latencies at the coordinator node to make gathering point similar to the case of standard writes. */ - public static IWriteResponseHandler mutateCounter(CounterMutation cm, String localDataCenter) throws UnavailableException, IOException + public static IWriteResponseHandler mutateCounter(CounterMutation cm, String localDataCenter) throws UnavailableException, OverloadedException, IOException { - InetAddress endpoint = findSuitableEndpoint(cm.getTable(), cm.key(), localDataCenter); + InetAddress endpoint = findSuitableEndpoint(cm.getTable(), cm.key(), localDataCenter, cm.consistency()); if (endpoint.equals(FBUtilities.getBroadcastAddress())) { @@ -507,12 +514,13 @@ public class StorageProxy implements StorageProxyMBean * is unclear we want to mix those latencies with read latencies, so this * may be a bit involved. */ - private static InetAddress findSuitableEndpoint(String table, ByteBuffer key, String localDataCenter) throws UnavailableException + private static InetAddress findSuitableEndpoint(String table, ByteBuffer key, String localDataCenter, ConsistencyLevel cl) throws UnavailableException { IEndpointSnitch snitch = DatabaseDescriptor.getEndpointSnitch(); List endpoints = StorageService.instance.getLiveNaturalEndpoints(table, key); if (endpoints.isEmpty()) - throw new UnavailableException(); + // TODO have a way to compute the consistency level + throw new UnavailableException(cl, cl.blockFor(table), 0); List localEndpoints = new ArrayList(); for (InetAddress endpoint : endpoints) @@ -532,18 +540,18 @@ public class StorageProxy implements StorageProxyMBean } } - - // Must be called on a replica of the mutation. This replica becomes the // leader of this mutation. - public static IWriteResponseHandler applyCounterMutationOnLeader(CounterMutation cm, String localDataCenter) throws UnavailableException, IOException + public static IWriteResponseHandler applyCounterMutationOnLeader(CounterMutation cm, String localDataCenter) + throws UnavailableException, IOException, OverloadedException { return performWrite(cm, cm.consistency(), localDataCenter, counterWritePerformer); } // Same as applyCounterMutationOnLeader but must with the difference that it use the MUTATION stage to execute the write (while // applyCounterMutationOnLeader assumes it is on the MUTATION stage already) - public static IWriteResponseHandler applyCounterMutationOnCoordinator(CounterMutation cm, String localDataCenter) throws UnavailableException, IOException + public static IWriteResponseHandler applyCounterMutationOnCoordinator(CounterMutation cm, String localDataCenter) + throws UnavailableException, IOException, OverloadedException { return performWrite(cm, cm.consistency(), localDataCenter, counterWriteOnCoordinatorPerformer); } @@ -573,7 +581,7 @@ public class StorageProxy implements StorageProxyMBean // and we want to avoid blocking too much the MUTATION stage StageManager.getStage(Stage.REPLICATE_ON_WRITE).execute(new DroppableRunnable(MessagingService.Verb.READ) { - public void runMayThrow() throws IOException, TimeoutException, UnavailableException + public void runMayThrow() throws IOException, OverloadedException { // send mutation to other replica sendToHintedEndpoints(cm.makeReplicationMutation(), targets, responseHandler, localDataCenter, consistency_level); @@ -597,16 +605,16 @@ public class StorageProxy implements StorageProxyMBean * a specific set of column names from a given column family. */ public static List read(List commands, ConsistencyLevel consistency_level) - throws IOException, UnavailableException, TimeoutException, InvalidRequestException + throws IOException, UnavailableException, IsBootstrappingException, ReadTimeoutException { if (StorageService.instance.isBootstrapMode() && !systemTableQuery(commands)) { readMetrics.unavailables.mark(); ClientRequestMetrics.readUnavailables.inc(); - throw new UnavailableException(); + throw new IsBootstrappingException(); } long startTime = System.nanoTime(); - List rows; + List rows = null; try { rows = fetchRows(commands, consistency_level); @@ -617,7 +625,7 @@ public class StorageProxy implements StorageProxyMBean ClientRequestMetrics.readUnavailables.inc(); throw e; } - catch (TimeoutException e) + catch (ReadTimeoutException e) { readMetrics.timeouts.mark(); ClientRequestMetrics.readTimeouts.inc(); @@ -641,7 +649,8 @@ public class StorageProxy implements StorageProxyMBean * 4. If the digests (if any) match the data return the data * 5. else carry out read repair by getting data from all the nodes. */ - private static List fetchRows(List initialCommands, ConsistencyLevel consistency_level) throws IOException, UnavailableException, TimeoutException + private static List fetchRows(List initialCommands, ConsistencyLevel consistency_level) + throws IOException, UnavailableException, ReadTimeoutException { List rows = new ArrayList(initialCommands.size()); List commandsToRetry = Collections.emptyList(); @@ -730,7 +739,7 @@ public class StorageProxy implements StorageProxyMBean if (logger.isDebugEnabled()) logger.debug("Read: " + (System.currentTimeMillis() - startTime2) + " ms."); } - catch (TimeoutException ex) + catch (ReadTimeoutException ex) { if (logger.isDebugEnabled()) logger.debug("Read timeout: {}", ex.toString()); @@ -769,9 +778,17 @@ public class StorageProxy implements StorageProxyMBean { ReadCommand command = repairCommands.get(i); RepairCallback handler = repairResponseHandlers.get(i); - // wait for the repair writes to be acknowledged, to minimize impact on any replica that's - // behind on writes in case the out-of-sync row is read multiple times in quick succession - FBUtilities.waitOnFutures(handler.resolver.repairResults, DatabaseDescriptor.getWriteRpcTimeout()); + try + { + // wait for the repair writes to be acknowledged, to minimize impact on any replica that's + // behind on writes in case the out-of-sync row is read multiple times in quick succession + FBUtilities.waitOnFutures(handler.resolver.repairResults, DatabaseDescriptor.getWriteRpcTimeout()); + } + catch (TimeoutException e) + { + int blockFor = consistency_level.blockFor(command.getKeyspace()); + throw new ReadTimeoutException(consistency_level, blockFor, blockFor, true); + } Row row; try @@ -865,7 +882,7 @@ public class StorageProxy implements StorageProxyMBean } public static List getRangeSlice(RangeSliceCommand command, ConsistencyLevel consistency_level) - throws IOException, UnavailableException, TimeoutException + throws IOException, UnavailableException, ReadTimeoutException { if (logger.isDebugEnabled()) logger.debug("Command/ConsistencyLevel is {}/{}", command.toString(), consistency_level); @@ -927,7 +944,9 @@ public class StorageProxy implements StorageProxyMBean { if (logger.isDebugEnabled()) logger.debug("Range slice timeout: {}", ex.toString()); - throw ex; + // We actually got all response at that point + int blockFor = consistency_level.blockFor(command.keyspace); + throw new ReadTimeoutException(consistency_level, blockFor, blockFor, true); } catch (DigestMismatchException e) { @@ -1208,7 +1227,8 @@ public class StorageProxy implements StorageProxyMBean // Since the truncate operation is so aggressive and is typically only // invoked by an admin, for simplicity we require that all nodes are up // to perform the operation. - throw new UnavailableException(); + int liveMembers = Gossiper.instance.getLiveMembers().size(); + throw new UnavailableException(ConsistencyLevel.ALL, liveMembers + Gossiper.instance.getUnreachableMembers().size(), liveMembers); } Set allEndpoints = Gossiper.instance.getLiveMembers(); @@ -1239,7 +1259,7 @@ public class StorageProxy implements StorageProxyMBean public interface WritePerformer { - public void apply(IMutation mutation, Collection targets, IWriteResponseHandler responseHandler, String localDataCenter, ConsistencyLevel consistency_level) throws IOException, UnavailableException; + public void apply(IMutation mutation, Collection targets, IWriteResponseHandler responseHandler, String localDataCenter, ConsistencyLevel consistency_level) throws IOException, OverloadedException; } private static abstract class DroppableRunnable implements Runnable diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index 4f06f1cd05..cc947275df 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -33,6 +33,7 @@ import javax.management.ObjectName; import static com.google.common.base.Charsets.ISO_8859_1; import com.google.common.collect.*; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.log4j.Level; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -47,6 +48,7 @@ import org.apache.cassandra.db.Table; import org.apache.cassandra.db.commitlog.CommitLog; import org.apache.cassandra.dht.*; import org.apache.cassandra.dht.Range; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.*; import org.apache.cassandra.io.sstable.SSTableDeletingTask; import org.apache.cassandra.io.sstable.SSTableLoader; @@ -483,7 +485,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe } } - private void joinTokenRing(int delay) throws IOException, org.apache.cassandra.config.ConfigurationException + private void joinTokenRing(int delay) throws IOException, ConfigurationException { logger.info("Starting up server gossip"); joined = true; @@ -2883,7 +2885,8 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe return old; } - public void truncate(String keyspace, String columnFamily) throws UnavailableException, TimeoutException, IOException + public void truncate(String keyspace, String columnFamily) + throws org.apache.cassandra.exceptions.UnavailableException, TimeoutException, IOException { StorageProxy.truncateBlocking(keyspace, columnFamily); } diff --git a/src/java/org/apache/cassandra/service/StorageServiceMBean.java b/src/java/org/apache/cassandra/service/StorageServiceMBean.java index 8ad047e550..77e984375d 100644 --- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java +++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java @@ -26,9 +26,9 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.apache.cassandra.config.ConfigurationException; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.UnavailableException; public interface StorageServiceMBean @@ -385,7 +385,7 @@ public interface StorageServiceMBean public boolean isNativeTransportRunning(); // allows a node that have been started without joining the ring to join it - public void joinRing() throws IOException, org.apache.cassandra.config.ConfigurationException; + public void joinRing() throws IOException, ConfigurationException; public boolean isJoined(); public int getExceptionCount(); diff --git a/src/java/org/apache/cassandra/service/WriteResponseHandler.java b/src/java/org/apache/cassandra/service/WriteResponseHandler.java index 0164c321ce..5b0f64c134 100644 --- a/src/java/org/apache/cassandra/service/WriteResponseHandler.java +++ b/src/java/org/apache/cassandra/service/WriteResponseHandler.java @@ -26,10 +26,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.db.Table; +import org.apache.cassandra.exceptions.UnavailableException; import org.apache.cassandra.gms.FailureDetector; import org.apache.cassandra.net.MessageIn; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.utils.FBUtilities; /** @@ -45,7 +45,7 @@ public class WriteResponseHandler extends AbstractWriteResponseHandler protected WriteResponseHandler(Collection writeEndpoints, ConsistencyLevel consistencyLevel, String table) { super(writeEndpoints, consistencyLevel); - blockFor = determineBlockFor(table); + blockFor = consistencyLevel.blockFor(table); responses = new AtomicInteger(blockFor); } @@ -77,25 +77,9 @@ public class WriteResponseHandler extends AbstractWriteResponseHandler return blockFor - responses.get(); } - protected int determineBlockFor(String table) + protected int blockFor() { - switch (consistencyLevel) - { - case ONE: - return 1; - case ANY: - return 1; - case TWO: - return 2; - case THREE: - return 3; - case QUORUM: - return (Table.open(table).getReplicationStrategy().getReplicationFactor() / 2) + 1; - case ALL: - return Table.open(table).getReplicationStrategy().getReplicationFactor(); - default: - throw new UnsupportedOperationException("invalid consistency level: " + consistencyLevel.toString()); - } + return blockFor; } public void assureSufficientLiveNodes() throws UnavailableException @@ -106,7 +90,7 @@ public class WriteResponseHandler extends AbstractWriteResponseHandler // Thus we include the local node (coordinator) as a valid replica if it is there already. int effectiveEndpoints = writeEndpoints.contains(FBUtilities.getBroadcastAddress()) ? writeEndpoints.size() : writeEndpoints.size() + 1; if (effectiveEndpoints < responses.get()) - throw new UnavailableException(); + throw new UnavailableException(consistencyLevel, responses.get(), effectiveEndpoints); return; } @@ -119,7 +103,7 @@ public class WriteResponseHandler extends AbstractWriteResponseHandler } if (liveNodes < responses.get()) { - throw new UnavailableException(); + throw new UnavailableException(consistencyLevel, responses.get(), liveNodes); } } diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java index 5eedcd7dcf..44c6038c92 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraServer.java +++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java @@ -46,6 +46,10 @@ import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.MarshalException; import org.apache.cassandra.db.marshal.TimeUUIDType; import org.apache.cassandra.dht.*; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.RequestExecutionException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.apache.cassandra.exceptions.ReadTimeoutException; import org.apache.cassandra.io.util.DataOutputBuffer; import org.apache.cassandra.locator.DynamicEndpointSnitch; import org.apache.cassandra.scheduler.IRequestScheduler; @@ -101,13 +105,13 @@ public class CassandraServer implements Cassandra.Iface return cState; } - protected Map readColumnFamily(List commands, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException + protected Map readColumnFamily(List commands, org.apache.cassandra.db.ConsistencyLevel consistency_level) + throws org.apache.cassandra.exceptions.InvalidRequestException, UnavailableException, TimedOutException { // TODO - Support multiple column families per row, right now row only contains 1 column family Map columnFamilyKeyMap = new HashMap(); - List rows; + List rows = null; try { schedule(DatabaseDescriptor.getReadRpcTimeout()); @@ -120,10 +124,9 @@ public class CassandraServer implements Cassandra.Iface release(); } } - catch (TimeoutException e) + catch (RequestExecutionException e) { - logger.debug("... timed out"); - throw new TimedOutException(); + ThriftConversion.rethrow(e); } catch (IOException e) { @@ -265,8 +268,8 @@ public class CassandraServer implements Cassandra.Iface return thriftSuperColumns; } - private Map> getSlice(List commands, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException + private Map> getSlice(List commands, org.apache.cassandra.db.ConsistencyLevel consistency_level) + throws org.apache.cassandra.exceptions.InvalidRequestException, UnavailableException, TimedOutException { Map columnFamilies = readColumnFamily(commands, consistency_level); Map> columnFamiliesMap = new HashMap>(); @@ -327,6 +330,10 @@ public class CassandraServer implements Cassandra.Iface return multigetSliceInternal(state().getKeyspace(), Collections.singletonList(key), column_parent, predicate, consistency_level).get(key); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -359,6 +366,10 @@ public class CassandraServer implements Cassandra.Iface state().hasColumnFamilyAccess(column_parent.column_family, Permission.READ); return multigetSliceInternal(state().getKeyspace(), keys, column_parent, predicate, consistency_level); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -366,12 +377,14 @@ public class CassandraServer implements Cassandra.Iface } private Map> multigetSliceInternal(String keyspace, List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException + throws org.apache.cassandra.exceptions.InvalidRequestException, UnavailableException, TimedOutException { CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family); ThriftValidation.validateColumnParent(metadata, column_parent); ThriftValidation.validatePredicate(metadata, column_parent, predicate); - ThriftValidation.validateConsistencyLevel(keyspace, consistency_level, RequestType.READ); + + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForRead(keyspace); List commands = new ArrayList(keys.size()); if (predicate.column_names != null) @@ -392,11 +405,11 @@ public class CassandraServer implements Cassandra.Iface } } - return getSlice(commands, consistency_level); + return getSlice(commands, consistencyLevel); } private ColumnOrSuperColumn internal_get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) - throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException + throws RequestValidationException, NotFoundException, UnavailableException, TimedOutException { ClientState cState = state(); cState.hasColumnFamilyAccess(column_path.column_family, Permission.READ); @@ -404,14 +417,15 @@ public class CassandraServer implements Cassandra.Iface CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_path.column_family); ThriftValidation.validateColumnPath(metadata, column_path); - ThriftValidation.validateConsistencyLevel(keyspace, consistency_level, RequestType.READ); + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForRead(keyspace); QueryPath path = new QueryPath(column_path.column_family, column_path.column == null ? null : column_path.super_column); List nameAsList = Arrays.asList(column_path.column == null ? column_path.super_column : column_path.column); ThriftValidation.validateKey(metadata, key); ReadCommand command = new SliceByNamesReadCommand(keyspace, key, path, nameAsList); - Map cfamilies = readColumnFamily(Arrays.asList(command), consistency_level); + Map cfamilies = readColumnFamily(Arrays.asList(command), consistencyLevel); ColumnFamily cf = cfamilies.get(StorageService.getPartitioner().decorateKey(command.key)); @@ -444,6 +458,10 @@ public class CassandraServer implements Cassandra.Iface { return internal_get(key, column_path, consistency_level); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -529,6 +547,10 @@ public class CassandraServer implements Cassandra.Iface return totalCount; } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -579,6 +601,10 @@ public class CassandraServer implements Cassandra.Iface } return counts; } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -586,7 +612,7 @@ public class CassandraServer implements Cassandra.Iface } private void internal_insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException + throws RequestValidationException, UnavailableException, TimedOutException { ClientState cState = state(); cState.hasColumnFamilyAccess(column_parent.column_family, Permission.WRITE); @@ -597,7 +623,7 @@ public class CassandraServer implements Cassandra.Iface // SuperColumn field is usually optional, but not when we're inserting if (metadata.cfType == ColumnFamilyType.Super && column_parent.super_column == null) { - throw new InvalidRequestException("missing mandatory super column name for super CF " + column_parent.column_family); + throw new org.apache.cassandra.exceptions.InvalidRequestException("missing mandatory super column name for super CF " + column_parent.column_family); } ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name)); ThriftValidation.validateColumnData(metadata, column, column_parent.super_column != null); @@ -609,7 +635,7 @@ public class CassandraServer implements Cassandra.Iface } catch (MarshalException e) { - throw new InvalidRequestException(e.getMessage()); + throw new org.apache.cassandra.exceptions.InvalidRequestException(e.getMessage()); } doInsert(consistency_level, Arrays.asList(rm)); } @@ -634,6 +660,10 @@ public class CassandraServer implements Cassandra.Iface { internal_insert(key, column_parent, column, consistency_level); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -641,7 +671,7 @@ public class CassandraServer implements Cassandra.Iface } private void internal_batch_mutate(Map>> mutation_map, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException + throws RequestValidationException, UnavailableException, TimedOutException { List cfamsSeen = new ArrayList(); List rowMutations = new ArrayList(); @@ -675,7 +705,7 @@ public class CassandraServer implements Cassandra.Iface RowMutation rm; if (metadata.getDefaultValidator().isCommutative()) { - ThriftValidation.validateCommutativeForWrite(metadata, consistency_level); + ThriftConversion.fromThrift(consistency_level).validateCounterForWrite(metadata); rmCounter = rmCounter == null ? new RowMutation(keyspace, key) : rmCounter; rm = rmCounter; } @@ -702,7 +732,7 @@ public class CassandraServer implements Cassandra.Iface if (rmStandard != null && !rmStandard.isEmpty()) rowMutations.add(rmStandard); if (rmCounter != null && !rmCounter.isEmpty()) - rowMutations.add(new org.apache.cassandra.db.CounterMutation(rmCounter, consistency_level)); + rowMutations.add(new org.apache.cassandra.db.CounterMutation(rmCounter, ThriftConversion.fromThrift(consistency_level))); } doInsert(consistency_level, rowMutations); @@ -731,6 +761,10 @@ public class CassandraServer implements Cassandra.Iface { internal_batch_mutate(mutation_map, consistency_level); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -738,7 +772,7 @@ public class CassandraServer implements Cassandra.Iface } private void internal_remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, boolean isCommutativeOp) - throws InvalidRequestException, UnavailableException, TimedOutException + throws RequestValidationException, UnavailableException, TimedOutException { ClientState cState = state(); cState.hasColumnFamilyAccess(column_path.column_family, Permission.WRITE); @@ -747,13 +781,13 @@ public class CassandraServer implements Cassandra.Iface ThriftValidation.validateKey(metadata, key); ThriftValidation.validateColumnPathOrParent(metadata, column_path); if (isCommutativeOp) - ThriftValidation.validateCommutativeForWrite(metadata, consistency_level); + ThriftConversion.fromThrift(consistency_level).validateCounterForWrite(metadata); RowMutation rm = new RowMutation(cState.getKeyspace(), key); rm.delete(new QueryPath(column_path), timestamp); if (isCommutativeOp) - doInsert(consistency_level, Arrays.asList(new CounterMutation(rm, consistency_level))); + doInsert(consistency_level, Arrays.asList(new CounterMutation(rm, ThriftConversion.fromThrift(consistency_level)))); else doInsert(consistency_level, Arrays.asList(rm)); } @@ -778,22 +812,32 @@ public class CassandraServer implements Cassandra.Iface { internal_remove(key, column_path, timestamp, consistency_level, false); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); } } - private void doInsert(ConsistencyLevel consistency_level, List mutations) throws UnavailableException, TimedOutException, InvalidRequestException + private void doInsert(ConsistencyLevel consistency_level, List mutations) + throws UnavailableException, TimedOutException, org.apache.cassandra.exceptions.InvalidRequestException { - ThriftValidation.validateConsistencyLevel(state().getKeyspace(), consistency_level, RequestType.WRITE); + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForWrite(state().getKeyspace()); if (mutations.isEmpty()) return; schedule(DatabaseDescriptor.getWriteRpcTimeout()); try { - StorageProxy.mutate(mutations, consistency_level); + StorageProxy.mutate(mutations, consistencyLevel); + } + catch (RequestExecutionException e) + { + ThriftConversion.rethrow(e); } finally { @@ -803,13 +847,20 @@ public class CassandraServer implements Cassandra.Iface public KsDef describe_keyspace(String table) throws NotFoundException, InvalidRequestException { - state().hasKeyspaceSchemaAccess(Permission.READ); + try + { + state().hasKeyspaceSchemaAccess(Permission.READ); - KSMetaData ksm = Schema.instance.getTableDefinition(table); - if (ksm == null) - throw new NotFoundException(); + KSMetaData ksm = Schema.instance.getTableDefinition(table); + if (ksm == null) + throw new NotFoundException(); - return ksm.toThrift(); + return ksm.toThrift(); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } } public List get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level) @@ -844,51 +895,59 @@ public class CassandraServer implements Cassandra.Iface ThriftValidation.validateColumnParent(metadata, column_parent); ThriftValidation.validatePredicate(metadata, column_parent, predicate); ThriftValidation.validateKeyRange(metadata, column_parent.super_column, range); - ThriftValidation.validateConsistencyLevel(keyspace, consistency_level, RequestType.READ); + + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForRead(keyspace); List rows = null; + + IPartitioner p = StorageService.getPartitioner(); + AbstractBounds bounds; + if (range.start_key == null) + { + Token.TokenFactory tokenFactory = p.getTokenFactory(); + Token left = tokenFactory.fromString(range.start_token); + Token right = tokenFactory.fromString(range.end_token); + bounds = Range.makeRowRange(left, right, p); + } + else + { + bounds = new Bounds(RowPosition.forKey(range.start_key, p), RowPosition.forKey( + range.end_key, p)); + } + schedule(DatabaseDescriptor.getRangeRpcTimeout()); try { - IPartitioner p = StorageService.getPartitioner(); - AbstractBounds bounds; - if (range.start_key == null) - { - Token.TokenFactory tokenFactory = p.getTokenFactory(); - Token left = tokenFactory.fromString(range.start_token); - Token right = tokenFactory.fromString(range.end_token); - bounds = Range.makeRowRange(left, right, p); - } - else - { - bounds = new Bounds(RowPosition.forKey(range.start_key, p), RowPosition.forKey( - range.end_key, p)); - } - schedule(DatabaseDescriptor.getRangeRpcTimeout()); - try - { - IFilter filter = ThriftValidation.asIFilter(predicate, - metadata.getComparatorFor(column_parent.super_column)); - rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_parent, filter, bounds, - range.row_filter, range.count), consistency_level); - } - finally - { - release(); - } - assert rows != null; + IFilter filter = ThriftValidation.asIFilter(predicate, + metadata.getComparatorFor(column_parent.super_column)); + rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_parent, filter, bounds, + range.row_filter, range.count), consistencyLevel); } - catch (TimeoutException e) + finally { - logger.debug("... timed out"); - throw new TimedOutException(); - } - catch (IOException e) - { - throw new RuntimeException(e); + release(); } + assert rows != null; return thriftifyKeySlices(rows, column_parent, predicate); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } + catch (ReadTimeoutException e) + { + logger.debug("... timed out"); + throw ThriftConversion.toThrift(e); + } + catch (org.apache.cassandra.exceptions.UnavailableException e) + { + throw ThriftConversion.toThrift(e); + } + catch (IOException e) + { + throw new RuntimeException(e); + } finally { Tracing.instance().stopSession(); @@ -921,7 +980,9 @@ public class CassandraServer implements Cassandra.Iface CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_family); ThriftValidation.validateKeyRange(metadata, null, range); - ThriftValidation.validateConsistencyLevel(keyspace, consistency_level, RequestType.READ); + + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForRead(keyspace); SlicePredicate predicate = new SlicePredicate().setSlice_range(new SliceRange(start_column, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, -1)); @@ -945,33 +1006,38 @@ public class CassandraServer implements Cassandra.Iface } List rows; + schedule(DatabaseDescriptor.getRangeRpcTimeout()); try { - schedule(DatabaseDescriptor.getRangeRpcTimeout()); - try - { - IFilter filter = ThriftValidation.asIFilter(predicate, metadata.comparator); - rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_family, null, filter, - bounds, range.row_filter, range.count, true, true), consistency_level); - } - finally - { - release(); - } - assert rows != null; + IFilter filter = ThriftValidation.asIFilter(predicate, metadata.comparator); + rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_family, null, filter, + bounds, range.row_filter, range.count, true, true), consistencyLevel); } - catch (TimeoutException e) + finally { - logger.debug("... timed out"); - throw new TimedOutException(); - } - catch (IOException e) - { - throw new RuntimeException(e); + release(); } + assert rows != null; return thriftifyKeySlices(rows, new ColumnParent(column_family), predicate); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } + catch (ReadTimeoutException e) + { + logger.debug("... timed out"); + throw ThriftConversion.toThrift(e); + } + catch (org.apache.cassandra.exceptions.UnavailableException e) + { + throw ThriftConversion.toThrift(e); + } + catch (IOException e) + { + throw new RuntimeException(e); + } finally { Tracing.instance().stopSession(); @@ -991,7 +1057,8 @@ public class CassandraServer implements Cassandra.Iface return keySlices; } - public List get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + public List get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException, TException { if (startSessionIfRequested()) { @@ -1009,7 +1076,6 @@ public class CassandraServer implements Cassandra.Iface try { - ClientState cState = state(); cState.hasColumnFamilyAccess(column_parent.column_family, Permission.READ); String keyspace = cState.getKeyspace(); @@ -1017,7 +1083,8 @@ public class CassandraServer implements Cassandra.Iface ThriftValidation.validateColumnParent(metadata, column_parent); ThriftValidation.validatePredicate(metadata, column_parent, column_predicate); ThriftValidation.validateIndexClauses(metadata, index_clause); - ThriftValidation.validateConsistencyLevel(keyspace, consistency_level, RequestType.READ); + org.apache.cassandra.db.ConsistencyLevel consistencyLevel = ThriftConversion.fromThrift(consistency_level); + consistencyLevel.validateForRead(keyspace); IPartitioner p = StorageService.getPartitioner(); AbstractBounds bounds = new Bounds(RowPosition.forKey(index_clause.start_key, p), @@ -1033,23 +1100,25 @@ public class CassandraServer implements Cassandra.Iface index_clause.expressions, index_clause.count); - List rows; - try - { - rows = StorageProxy.getRangeSlice(command, consistency_level); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - catch (TimeoutException e) - { - logger.debug("... timed out"); - throw new TimedOutException(); - } - + List rows = StorageProxy.getRangeSlice(command, consistencyLevel); return thriftifyKeySlices(rows, column_parent, column_predicate); - + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } + catch (ReadTimeoutException e) + { + logger.debug("... timed out"); + throw ThriftConversion.toThrift(e); + } + catch (org.apache.cassandra.exceptions.UnavailableException e) + { + throw ThriftConversion.toThrift(e); + } + catch (IOException e) + { + throw new RuntimeException(e); } finally { @@ -1059,22 +1128,29 @@ public class CassandraServer implements Cassandra.Iface public List describe_keyspaces() throws TException, InvalidRequestException { - state().hasKeyspaceSchemaAccess(Permission.READ); - - Set keyspaces = Schema.instance.getTables(); - List ksset = new ArrayList(keyspaces.size()); - for (String ks : keyspaces) + try { - try + state().hasKeyspaceSchemaAccess(Permission.READ); + + Set keyspaces = Schema.instance.getTables(); + List ksset = new ArrayList(keyspaces.size()); + for (String ks : keyspaces) { - ksset.add(describe_keyspace(ks)); - } - catch (NotFoundException nfe) - { - logger.info("Failed to find metadata for keyspace '" + ks + "'. Continuing... "); + try + { + ksset.add(describe_keyspace(ks)); + } + catch (NotFoundException nfe) + { + logger.info("Failed to find metadata for keyspace '" + ks + "'. Continuing... "); + } } + return ksset; + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); } - return ksset; } public String describe_cluster_name() throws TException @@ -1087,9 +1163,16 @@ public class CassandraServer implements Cassandra.Iface return Constants.VERSION; } - public List describe_ring(String keyspace)throws InvalidRequestException + public List describe_ring(String keyspace) throws InvalidRequestException { - return StorageService.instance.describeRing(keyspace); + try + { + return StorageService.instance.describeRing(keyspace); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } } public Map describe_token_map() throws InvalidRequestException @@ -1112,15 +1195,22 @@ public class CassandraServer implements Cassandra.Iface public List describe_splits(String cfName, String start_token, String end_token, int keys_per_split) throws TException, InvalidRequestException { - // TODO: add keyspace authorization call post CASSANDRA-1425 - Token.TokenFactory tf = StorageService.getPartitioner().getTokenFactory(); - List tokens = StorageService.instance.getSplits(state().getKeyspace(), cfName, new Range(tf.fromString(start_token), tf.fromString(end_token)), keys_per_split); - List splits = new ArrayList(tokens.size()); - for (Token token : tokens) + try { - splits.add(tf.toString(token)); + // TODO: add keyspace authorization call post CASSANDRA-1425 + Token.TokenFactory tf = StorageService.getPartitioner().getTokenFactory(); + List tokens = StorageService.instance.getSplits(state().getKeyspace(), cfName, new Range(tf.fromString(start_token), tf.fromString(end_token)), keys_per_split); + List splits = new ArrayList(tokens.size()); + for (Token token : tokens) + { + splits.add(tf.toString(token)); + } + return splits; + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); } - return splits; } public void login(AuthenticationRequest auth_request) throws AuthenticationException, AuthorizationException, TException @@ -1155,10 +1245,10 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("add_column_family"); - state().hasColumnFamilySchemaAccess(Permission.WRITE); try { + state().hasColumnFamilySchemaAccess(Permission.WRITE); cf_def.unsetId(); // explicitly ignore any id set by client (Hector likes to set zero) CFMetaData cfm = CFMetaData.fromThrift(cf_def); if (cfm.getBloomFilterFpChance() == null) @@ -1167,11 +1257,9 @@ public class CassandraServer implements Cassandra.Iface MigrationManager.announceNewColumnFamily(cfm); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } @@ -1181,18 +1269,16 @@ public class CassandraServer implements Cassandra.Iface logger.debug("drop_column_family"); ClientState cState = state(); - cState.hasColumnFamilySchemaAccess(Permission.WRITE); try { + cState.hasColumnFamilySchemaAccess(Permission.WRITE); MigrationManager.announceColumnFamilyDrop(cState.getKeyspace(), column_family); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } @@ -1200,21 +1286,21 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("add_keyspace"); - ThriftValidation.validateKeyspaceNotSystem(ks_def.name); - state().hasKeyspaceSchemaAccess(Permission.WRITE); - ThriftValidation.validateKeyspaceNotYetExisting(ks_def.name); - - // generate a meaningful error if the user setup keyspace and/or column definition incorrectly - for (CfDef cf : ks_def.cf_defs) - { - if (!cf.getKeyspace().equals(ks_def.getName())) - { - throw new InvalidRequestException("CfDef (" + cf.getName() +") had a keyspace definition that did not match KsDef"); - } - } - try { + ThriftValidation.validateKeyspaceNotSystem(ks_def.name); + state().hasKeyspaceSchemaAccess(Permission.WRITE); + ThriftValidation.validateKeyspaceNotYetExisting(ks_def.name); + + // generate a meaningful error if the user setup keyspace and/or column definition incorrectly + for (CfDef cf : ks_def.cf_defs) + { + if (!cf.getKeyspace().equals(ks_def.getName())) + { + throw new InvalidRequestException("CfDef (" + cf.getName() +") had a keyspace definition that did not match KsDef"); + } + } + Collection cfDefs = new ArrayList(ks_def.cf_defs.size()); for (CfDef cf_def : ks_def.cf_defs) { @@ -1226,11 +1312,9 @@ public class CassandraServer implements Cassandra.Iface MigrationManager.announceNewKeyspace(KSMetaData.fromThrift(ks_def, cfDefs.toArray(new CFMetaData[cfDefs.size()]))); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } @@ -1238,19 +1322,17 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("drop_keyspace"); - ThriftValidation.validateKeyspaceNotSystem(keyspace); - state().hasKeyspaceSchemaAccess(Permission.WRITE); - try { + ThriftValidation.validateKeyspaceNotSystem(keyspace); + state().hasKeyspaceSchemaAccess(Permission.WRITE); + MigrationManager.announceKeyspaceDrop(keyspace); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } @@ -1261,22 +1343,20 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("update_keyspace"); - ThriftValidation.validateKeyspaceNotSystem(ks_def.name); - state().hasKeyspaceSchemaAccess(Permission.WRITE); - ThriftValidation.validateTable(ks_def.name); - if (ks_def.getCf_defs() != null && ks_def.getCf_defs().size() > 0) - throw new InvalidRequestException("Keyspace update must not contain any column family definitions."); - try { + ThriftValidation.validateKeyspaceNotSystem(ks_def.name); + state().hasKeyspaceSchemaAccess(Permission.WRITE); + ThriftValidation.validateTable(ks_def.name); + if (ks_def.getCf_defs() != null && ks_def.getCf_defs().size() > 0) + throw new InvalidRequestException("Keyspace update must not contain any column family definitions."); + MigrationManager.announceKeyspaceUpdate(KSMetaData.fromThrift(ks_def)); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } @@ -1284,45 +1364,44 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("update_column_family"); - state().hasColumnFamilySchemaAccess(Permission.WRITE); - if (cf_def.keyspace == null || cf_def.name == null) - throw new InvalidRequestException("Keyspace and CF name must be set."); - CFMetaData oldCfm = Schema.instance.getCFMetaData(cf_def.keyspace, cf_def.name); - if (oldCfm == null) - throw new InvalidRequestException("Could not find column family definition to modify."); - try { + state().hasColumnFamilySchemaAccess(Permission.WRITE); + if (cf_def.keyspace == null || cf_def.name == null) + throw new InvalidRequestException("Keyspace and CF name must be set."); + CFMetaData oldCfm = Schema.instance.getCFMetaData(cf_def.keyspace, cf_def.name); + if (oldCfm == null) + throw new InvalidRequestException("Could not find column family definition to modify."); + CFMetaData.applyImplicitDefaults(cf_def); CFMetaData cfm = CFMetaData.fromThrift(cf_def); cfm.addDefaultIndexNames(); MigrationManager.announceColumnFamilyUpdate(cfm); return Schema.instance.getVersion().toString(); } - catch (ConfigurationException e) + catch (RequestValidationException e) { - InvalidRequestException ex = new InvalidRequestException(e.getMessage()); - ex.initCause(e); - throw ex; + throw ThriftConversion.toThrift(e); } } public void truncate(String cfname) throws InvalidRequestException, UnavailableException, TimedOutException, TException { ClientState cState = state(); - cState.hasColumnFamilyAccess(cfname, Permission.WRITE); - - if (startSessionIfRequested()) - { - Tracing.instance().begin("truncate", ImmutableMap.of("cf", cfname, "ks", cState.getKeyspace())); - } - else - { - logger.debug("truncating {}.{}", cState.getKeyspace(), cfname); - } try { + cState.hasColumnFamilyAccess(cfname, Permission.WRITE); + + if (startSessionIfRequested()) + { + Tracing.instance().begin("truncate", ImmutableMap.of("cf", cfname, "ks", cState.getKeyspace())); + } + else + { + logger.debug("truncating {}.{}", cState.getKeyspace(), cfname); + } + schedule(DatabaseDescriptor.getTruncateRpcTimeout()); try { @@ -1333,6 +1412,14 @@ public class CassandraServer implements Cassandra.Iface release(); } } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } + catch (org.apache.cassandra.exceptions.UnavailableException e) + { + throw ThriftConversion.toThrift(e); + } catch (TimeoutException e) { logger.debug("... timed out"); @@ -1350,9 +1437,15 @@ public class CassandraServer implements Cassandra.Iface public void set_keyspace(String keyspace) throws InvalidRequestException, TException { - ThriftValidation.validateTable(keyspace); - - state().setKeyspace(keyspace); + try + { + ThriftValidation.validateTable(keyspace); + state().setKeyspace(keyspace); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } } public Map> describe_schema_versions() throws TException, InvalidRequestException @@ -1387,27 +1480,28 @@ public class CassandraServer implements Cassandra.Iface CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family, true); ThriftValidation.validateKey(metadata, key); - ThriftValidation.validateCommutativeForWrite(metadata, consistency_level); + ThriftConversion.fromThrift(consistency_level).validateCounterForWrite(metadata); ThriftValidation.validateColumnParent(metadata, column_parent); // SuperColumn field is usually optional, but not when we're adding if (metadata.cfType == ColumnFamilyType.Super && column_parent.super_column == null) - { - throw new InvalidRequestException("missing mandatory super column name for super CF " - + column_parent.column_family); - } + throw new InvalidRequestException("missing mandatory super column name for super CF " + column_parent.column_family); + ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name)); RowMutation rm = new RowMutation(keyspace, key); try { - rm.addCounter(new QueryPath(column_parent.column_family, column_parent.super_column, column.name), - column.value); + rm.addCounter(new QueryPath(column_parent.column_family, column_parent.super_column, column.name), column.value); } catch (MarshalException e) { throw new InvalidRequestException(e.getMessage()); } - doInsert(consistency_level, Arrays.asList(new CounterMutation(rm, consistency_level))); + doInsert(consistency_level, Arrays.asList(new CounterMutation(rm, ThriftConversion.fromThrift(consistency_level)))); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); } finally { @@ -1416,7 +1510,7 @@ public class CassandraServer implements Cassandra.Iface } public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) - throws InvalidRequestException, UnavailableException, TimedOutException, TException + throws InvalidRequestException, UnavailableException, TimedOutException, TException { if (startSessionIfRequested()) { @@ -1434,6 +1528,10 @@ public class CassandraServer implements Cassandra.Iface { internal_remove(key, path, System.currentTimeMillis(), consistency_level, true); } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -1520,6 +1618,15 @@ public class CassandraServer implements Cassandra.Iface else return org.apache.cassandra.cql3.QueryProcessor.process(queryString, cState).toThriftResult(); } + catch (RequestExecutionException e) + { + ThriftConversion.rethrow(e); + return null; + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -1532,13 +1639,20 @@ public class CassandraServer implements Cassandra.Iface if (logger.isDebugEnabled()) logger.debug("prepare_cql_query"); - String queryString = uncompress(query,compression); + try + { + String queryString = uncompress(query,compression); - ClientState cState = state(); - if (cState.getCQLVersion().major == 2) - return QueryProcessor.prepare(queryString, cState); - else - return org.apache.cassandra.cql3.QueryProcessor.prepare(queryString, cState).toThriftPreparedResult(); + ClientState cState = state(); + if (cState.getCQLVersion().major == 2) + return QueryProcessor.prepare(queryString, cState); + else + return org.apache.cassandra.cql3.QueryProcessor.prepare(queryString, cState).toThriftPreparedResult(); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } } public CqlResult execute_prepared_cql_query(int itemId, List bindVariables) @@ -1576,10 +1690,18 @@ public class CassandraServer implements Cassandra.Iface logger.trace("Retrieved prepared statement #{} with {} bind markers", itemId, statement.getBoundsTerms()); - return org.apache.cassandra.cql3.QueryProcessor.processPrepared(statement, cState, bindVariables) - .toThriftResult(); + return org.apache.cassandra.cql3.QueryProcessor.processPrepared(statement, cState, bindVariables).toThriftResult(); } } + catch (RequestExecutionException e) + { + ThriftConversion.rethrow(e); + return null; + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } finally { Tracing.instance().stopSession(); @@ -1590,7 +1712,14 @@ public class CassandraServer implements Cassandra.Iface { logger.debug("set_cql_version: " + version); - state().setCQLVersion(version); + try + { + state().setCQLVersion(version); + } + catch (RequestValidationException e) + { + throw ThriftConversion.toThrift(e); + } } public ByteBuffer trace_next_query() throws TException diff --git a/src/java/org/apache/cassandra/thrift/ThriftConversion.java b/src/java/org/apache/cassandra/thrift/ThriftConversion.java new file mode 100644 index 0000000000..ac823e961b --- /dev/null +++ b/src/java/org/apache/cassandra/thrift/ThriftConversion.java @@ -0,0 +1,92 @@ +/* + * 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.thrift; + +import org.apache.cassandra.exceptions.RequestExecutionException; +import org.apache.cassandra.exceptions.RequestTimeoutException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.apache.cassandra.exceptions.WriteTimeoutException; + +/** + * Static utility methods to convert internal structure to and from thrift ones. + */ +public class ThriftConversion +{ + public static ConsistencyLevel toThrift(org.apache.cassandra.db.ConsistencyLevel cl) + { + switch (cl) + { + case ANY: return ConsistencyLevel.ANY; + case ONE: return ConsistencyLevel.ONE; + case TWO: return ConsistencyLevel.TWO; + case THREE: return ConsistencyLevel.THREE; + case QUORUM: return ConsistencyLevel.QUORUM; + case ALL: return ConsistencyLevel.ALL; + case LOCAL_QUORUM: return ConsistencyLevel.LOCAL_QUORUM; + case EACH_QUORUM: return ConsistencyLevel.EACH_QUORUM; + } + throw new AssertionError(); + } + + public static org.apache.cassandra.db.ConsistencyLevel fromThrift(ConsistencyLevel cl) + { + switch (cl) + { + case ANY: return org.apache.cassandra.db.ConsistencyLevel.ANY; + case ONE: return org.apache.cassandra.db.ConsistencyLevel.ONE; + case TWO: return org.apache.cassandra.db.ConsistencyLevel.TWO; + case THREE: return org.apache.cassandra.db.ConsistencyLevel.THREE; + case QUORUM: return org.apache.cassandra.db.ConsistencyLevel.QUORUM; + case ALL: return org.apache.cassandra.db.ConsistencyLevel.ALL; + case LOCAL_QUORUM: return org.apache.cassandra.db.ConsistencyLevel.LOCAL_QUORUM; + case EACH_QUORUM: return org.apache.cassandra.db.ConsistencyLevel.EACH_QUORUM; + } + throw new AssertionError(); + } + + public static void rethrow(RequestExecutionException e) throws UnavailableException, TimedOutException + { + if (e instanceof RequestTimeoutException) + throw toThrift((RequestTimeoutException)e); + else + throw new UnavailableException(); + } + + public static InvalidRequestException toThrift(RequestValidationException e) + { + return new InvalidRequestException(e.getMessage()); + } + + public static InvalidRequestException toThrift(org.apache.cassandra.exceptions.InvalidRequestException e) + { + return new InvalidRequestException(e.getMessage()); + } + + public static UnavailableException toThrift(org.apache.cassandra.exceptions.UnavailableException e) + { + return new UnavailableException(); + } + + public static TimedOutException toThrift(RequestTimeoutException e) + { + TimedOutException toe = new TimedOutException(); + if (e instanceof WriteTimeoutException) + toe.setAcknowledged_by(((WriteTimeoutException)e).received); + return toe; + } +} diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java b/src/java/org/apache/cassandra/thrift/ThriftValidation.java index d31515e772..36b3aca967 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java +++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java @@ -51,18 +51,19 @@ public class ThriftValidation { private static final Logger logger = LoggerFactory.getLogger(ThriftValidation.class); - public static void validateKey(CFMetaData metadata, ByteBuffer key) throws InvalidRequestException + public static void validateKey(CFMetaData metadata, ByteBuffer key) throws org.apache.cassandra.exceptions.InvalidRequestException { if (key == null || key.remaining() == 0) { - throw new InvalidRequestException("Key may not be empty"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Key may not be empty"); } // check that key can be handled by FBUtilities.writeShortByteArray if (key.remaining() > FBUtilities.MAX_UNSIGNED_SHORT) { - throw new InvalidRequestException("Key length of " + key.remaining() + - " is longer than maximum of " + FBUtilities.MAX_UNSIGNED_SHORT); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Key length of " + key.remaining() + + " is longer than maximum of " + + FBUtilities.MAX_UNSIGNED_SHORT); } try @@ -71,7 +72,7 @@ public class ThriftValidation } catch (MarshalException e) { - throw new InvalidRequestException(e.getMessage()); + throw new org.apache.cassandra.exceptions.InvalidRequestException(e.getMessage()); } } @@ -83,61 +84,33 @@ public class ThriftValidation } } - // Don't check that the table exists, validateTable or validateColumnFamily must be called beforehand. - public static void validateConsistencyLevel(String table, ConsistencyLevel cl, RequestType requestType) throws InvalidRequestException - { - switch (cl) - { - case ANY: - if (requestType == RequestType.READ) - throw new InvalidRequestException("ANY ConsistencyLevel is only supported for writes"); - break; - case LOCAL_QUORUM: - requireNetworkTopologyStrategy(table, cl); - break; - case EACH_QUORUM: - requireNetworkTopologyStrategy(table, cl); - if (requestType == RequestType.READ) - throw new InvalidRequestException("EACH_QUORUM ConsistencyLevel is only supported for writes"); - break; - } - } - - private static void requireNetworkTopologyStrategy(String table, ConsistencyLevel cl) throws InvalidRequestException - { - AbstractReplicationStrategy strategy = Table.open(table).getReplicationStrategy(); - if (!(strategy instanceof NetworkTopologyStrategy)) - throw new InvalidRequestException(String.format("consistency level %s not compatible with replication strategy (%s)", - cl, strategy.getClass().getName())); - } - - public static CFMetaData validateColumnFamily(String tablename, String cfName, boolean isCommutativeOp) throws InvalidRequestException + public static CFMetaData validateColumnFamily(String tablename, String cfName, boolean isCommutativeOp) throws org.apache.cassandra.exceptions.InvalidRequestException { CFMetaData metadata = validateColumnFamily(tablename, cfName); if (isCommutativeOp) { if (!metadata.getDefaultValidator().isCommutative()) - throw new InvalidRequestException("invalid operation for non commutative columnfamily " + cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for non commutative columnfamily " + cfName); } else { if (metadata.getDefaultValidator().isCommutative()) - throw new InvalidRequestException("invalid operation for commutative columnfamily " + cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for commutative columnfamily " + cfName); } return metadata; } // To be used when the operation should be authorized whether this is a counter CF or not - public static CFMetaData validateColumnFamily(String tablename, String cfName) throws InvalidRequestException + public static CFMetaData validateColumnFamily(String tablename, String cfName) throws org.apache.cassandra.exceptions.InvalidRequestException { validateTable(tablename); if (cfName.isEmpty()) - throw new InvalidRequestException("non-empty columnfamily is required"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("non-empty columnfamily is required"); CFMetaData metadata = Schema.instance.getCFMetaData(tablename, cfName); if (metadata == null) - throw new InvalidRequestException("unconfigured columnfamily " + cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("unconfigured columnfamily " + cfName); return metadata; } @@ -145,23 +118,23 @@ public class ThriftValidation /** * validates all parts of the path to the column, including the column name */ - public static void validateColumnPath(CFMetaData metadata, ColumnPath column_path) throws InvalidRequestException + public static void validateColumnPath(CFMetaData metadata, ColumnPath column_path) throws org.apache.cassandra.exceptions.InvalidRequestException { if (metadata.cfType == ColumnFamilyType.Standard) { if (column_path.super_column != null) { - throw new InvalidRequestException("supercolumn parameter is invalid for standard CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn parameter is invalid for standard CF " + metadata.cfName); } if (column_path.column == null) { - throw new InvalidRequestException("column parameter is not optional for standard CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("column parameter is not optional for standard CF " + metadata.cfName); } } else { if (column_path.super_column == null) - throw new InvalidRequestException("supercolumn parameter is not optional for super CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn parameter is not optional for super CF " + metadata.cfName); } if (column_path.column != null) { @@ -173,13 +146,13 @@ public class ThriftValidation } } - public static void validateColumnParent(CFMetaData metadata, ColumnParent column_parent) throws InvalidRequestException + public static void validateColumnParent(CFMetaData metadata, ColumnParent column_parent) throws org.apache.cassandra.exceptions.InvalidRequestException { if (metadata.cfType == ColumnFamilyType.Standard) { if (column_parent.super_column != null) { - throw new InvalidRequestException("columnfamily alone is required for standard CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("columnfamily alone is required for standard CF " + metadata.cfName); } } @@ -190,20 +163,21 @@ public class ThriftValidation } // column_path_or_parent is a ColumnPath for remove, where the "column" is optional even for a standard CF - static void validateColumnPathOrParent(CFMetaData metadata, ColumnPath column_path_or_parent) throws InvalidRequestException + static void validateColumnPathOrParent(CFMetaData metadata, ColumnPath column_path_or_parent) throws org.apache.cassandra.exceptions.InvalidRequestException { if (metadata.cfType == ColumnFamilyType.Standard) { if (column_path_or_parent.super_column != null) { - throw new InvalidRequestException("supercolumn may not be specified for standard CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn may not be specified for standard CF " + metadata.cfName); } } if (metadata.cfType == ColumnFamilyType.Super) { if (column_path_or_parent.super_column == null && column_path_or_parent.column != null) { - throw new InvalidRequestException("A column cannot be specified without specifying a super column for removal on super CF " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("A column cannot be specified without specifying a super column for removal on super CF " + + metadata.cfName); } } if (column_path_or_parent.column != null) @@ -220,41 +194,41 @@ public class ThriftValidation * Validates the column names but not the parent path or data */ private static void validateColumnNames(CFMetaData metadata, ByteBuffer superColumnName, Iterable column_names) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { if (superColumnName != null) { if (superColumnName.remaining() > IColumn.MAX_NAME_LENGTH) - throw new InvalidRequestException("supercolumn name length must not be greater than " + IColumn.MAX_NAME_LENGTH); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn name length must not be greater than " + IColumn.MAX_NAME_LENGTH); if (superColumnName.remaining() == 0) - throw new InvalidRequestException("supercolumn name must not be empty"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn name must not be empty"); if (metadata.cfType == ColumnFamilyType.Standard) - throw new InvalidRequestException("supercolumn specified to ColumnFamily " + metadata.cfName + " containing normal columns"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("supercolumn specified to ColumnFamily " + metadata.cfName + " containing normal columns"); } AbstractType comparator = metadata.getComparatorFor(superColumnName); for (ByteBuffer name : column_names) { if (name.remaining() > IColumn.MAX_NAME_LENGTH) - throw new InvalidRequestException("column name length must not be greater than " + IColumn.MAX_NAME_LENGTH); + throw new org.apache.cassandra.exceptions.InvalidRequestException("column name length must not be greater than " + IColumn.MAX_NAME_LENGTH); if (name.remaining() == 0) - throw new InvalidRequestException("column name must not be empty"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("column name must not be empty"); try { comparator.validate(name); } catch (MarshalException e) { - throw new InvalidRequestException(e.getMessage()); + throw new org.apache.cassandra.exceptions.InvalidRequestException(e.getMessage()); } } } - public static void validateColumnNames(CFMetaData metadata, ColumnParent column_parent, Iterable column_names) throws InvalidRequestException + public static void validateColumnNames(CFMetaData metadata, ColumnParent column_parent, Iterable column_names) throws org.apache.cassandra.exceptions.InvalidRequestException { validateColumnNames(metadata, column_parent.super_column, column_names); } - public static void validateRange(CFMetaData metadata, ColumnParent column_parent, SliceRange range) throws InvalidRequestException + public static void validateRange(CFMetaData metadata, ColumnParent column_parent, SliceRange range) throws org.apache.cassandra.exceptions.InvalidRequestException { AbstractType comparator = metadata.getComparatorFor(column_parent.super_column); try @@ -264,23 +238,23 @@ public class ThriftValidation } catch (MarshalException e) { - throw new InvalidRequestException(e.getMessage()); + throw new org.apache.cassandra.exceptions.InvalidRequestException(e.getMessage()); } if (range.count < 0) - throw new InvalidRequestException("get_slice requires non-negative count"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("get_slice requires non-negative count"); Comparator orderedComparator = range.isReversed() ? comparator.reverseComparator : comparator; if (range.start.remaining() > 0 && range.finish.remaining() > 0 && orderedComparator.compare(range.start, range.finish) > 0) { - throw new InvalidRequestException("range finish must come after start in the order of traversal"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("range finish must come after start in the order of traversal"); } } public static void validateColumnOrSuperColumn(CFMetaData metadata, ColumnOrSuperColumn cosc) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { boolean isCommutative = metadata.getDefaultValidator().isCommutative(); @@ -291,12 +265,12 @@ public class ThriftValidation if (cosc.counter_super_column == null) nulls++; if (nulls != 3) - throw new InvalidRequestException("ColumnOrSuperColumn must have one (and only one) of column, super_column, counter and counter_super_column"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("ColumnOrSuperColumn must have one (and only one) of column, super_column, counter and counter_super_column"); if (cosc.column != null) { if (isCommutative) - throw new InvalidRequestException("invalid operation for commutative columnfamily " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for commutative columnfamily " + metadata.cfName); validateTtl(cosc.column); validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column((ByteBuffer)null).setColumn(cosc.column.name)); @@ -306,7 +280,7 @@ public class ThriftValidation if (cosc.super_column != null) { if (isCommutative) - throw new InvalidRequestException("invalid operation for commutative columnfamily " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for commutative columnfamily " + metadata.cfName); for (Column c : cosc.super_column.columns) { @@ -318,7 +292,7 @@ public class ThriftValidation if (cosc.counter_column != null) { if (!isCommutative) - throw new InvalidRequestException("invalid operation for non commutative columnfamily " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for non commutative columnfamily " + metadata.cfName); validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column((ByteBuffer)null).setColumn(cosc.counter_column.name)); } @@ -326,25 +300,25 @@ public class ThriftValidation if (cosc.counter_super_column != null) { if (!isCommutative) - throw new InvalidRequestException("invalid operation for non commutative columnfamily " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("invalid operation for non commutative columnfamily " + metadata.cfName); for (CounterColumn c : cosc.counter_super_column.columns) validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column(cosc.counter_super_column.name).setColumn(c.name)); } } - private static void validateTtl(Column column) throws InvalidRequestException + private static void validateTtl(Column column) throws org.apache.cassandra.exceptions.InvalidRequestException { if (column.isSetTtl() && column.ttl <= 0) { - throw new InvalidRequestException("ttl must be positive"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("ttl must be positive"); } // if it's not set, then it should be zero -- here we are just checking to make sure Thrift doesn't change that contract with us. assert column.isSetTtl() || column.ttl == 0; } public static void validateMutation(CFMetaData metadata, Mutation mut) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { ColumnOrSuperColumn cosc = mut.column_or_supercolumn; Deletion del = mut.deletion; @@ -355,7 +329,7 @@ public class ThriftValidation if (nulls != 1) { - throw new InvalidRequestException("mutation must have one and only one of column_or_supercolumn or deletion"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("mutation must have one and only one of column_or_supercolumn or deletion"); } if (cosc != null) @@ -368,7 +342,7 @@ public class ThriftValidation } } - public static void validateDeletion(CFMetaData metadata, Deletion del) throws InvalidRequestException + public static void validateDeletion(CFMetaData metadata, Deletion del) throws org.apache.cassandra.exceptions.InvalidRequestException { if (del.super_column != null) @@ -378,13 +352,13 @@ public class ThriftValidation { validateSlicePredicate(metadata, del.super_column, del.predicate); if (del.predicate.slice_range != null) - throw new InvalidRequestException("Deletion does not yet support SliceRange predicates."); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Deletion does not yet support SliceRange predicates."); } if (metadata.cfType == ColumnFamilyType.Standard && del.super_column != null) { String msg = String.format("Deletion of super columns is not possible on a standard ColumnFamily (KeySpace=%s ColumnFamily=%s Deletion=%s)", metadata.ksName, metadata.cfName, del); - throw new InvalidRequestException(msg); + throw new org.apache.cassandra.exceptions.InvalidRequestException(msg); } if (metadata.getDefaultValidator().isCommutative()) @@ -394,14 +368,14 @@ public class ThriftValidation } else if (!del.isSetTimestamp()) { - throw new InvalidRequestException("Deletion timestamp is not optional for non commutative column family " + metadata.cfName); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Deletion timestamp is not optional for non commutative column family " + metadata.cfName); } } - public static void validateSlicePredicate(CFMetaData metadata, ByteBuffer scName, SlicePredicate predicate) throws InvalidRequestException + public static void validateSlicePredicate(CFMetaData metadata, ByteBuffer scName, SlicePredicate predicate) throws org.apache.cassandra.exceptions.InvalidRequestException { if (predicate.column_names == null && predicate.slice_range == null) - throw new InvalidRequestException("A SlicePredicate must be given a list of Columns, a SliceRange, or both"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("A SlicePredicate must be given a list of Columns, a SliceRange, or both"); if (predicate.slice_range != null) validateRange(metadata, new ColumnParent(metadata.cfName).setSuper_column(scName), predicate.slice_range); @@ -413,13 +387,13 @@ public class ThriftValidation /** * Validates the data part of the column (everything in the Column object but the name, which is assumed to be valid) */ - public static void validateColumnData(CFMetaData metadata, Column column, boolean isSubColumn) throws InvalidRequestException + public static void validateColumnData(CFMetaData metadata, Column column, boolean isSubColumn) throws org.apache.cassandra.exceptions.InvalidRequestException { validateTtl(column); if (!column.isSetValue()) - throw new InvalidRequestException("Column value is required"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Column value is required"); if (!column.isSetTimestamp()) - throw new InvalidRequestException("Column timestamp is required"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Column timestamp is required"); ColumnDefinition columnDef = metadata.getColumnDefinition(column.name); try @@ -432,20 +406,20 @@ public class ThriftValidation { if (logger.isDebugEnabled()) logger.debug("rejecting invalid value " + ByteBufferUtil.bytesToHex(summarize(column.value))); - throw new InvalidRequestException(String.format("(%s) [%s][%s][%s] failed validation", - me.getMessage(), - metadata.ksName, - metadata.cfName, - (isSubColumn ? metadata.subcolumnComparator : metadata.comparator).getString(column.name))); + throw new org.apache.cassandra.exceptions.InvalidRequestException(String.format("(%s) [%s][%s][%s] failed validation", + me.getMessage(), + metadata.ksName, + metadata.cfName, + (isSubColumn ? metadata.subcolumnComparator : metadata.comparator).getString(column.name))); } // Indexed column values cannot be larger than 64K. See CASSANDRA-3057/4240 for more details if (!Table.open(metadata.ksName).getColumnFamilyStore(metadata.cfName).indexManager.validate(column)) - throw new InvalidRequestException(String.format("Can't index column value of size %d for index %s in CF %s of KS %s", - column.value.remaining(), - columnDef.getIndexName(), - metadata.cfName, - metadata.ksName)); + throw new org.apache.cassandra.exceptions.InvalidRequestException(String.format("Can't index column value of size %d for index %s in CF %s of KS %s", + column.value.remaining(), + columnDef.getIndexName(), + metadata.cfName, + metadata.ksName)); } /** @@ -462,12 +436,12 @@ public class ThriftValidation public static void validatePredicate(CFMetaData metadata, ColumnParent column_parent, SlicePredicate predicate) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { if (predicate.column_names == null && predicate.slice_range == null) - throw new InvalidRequestException("predicate column_names and slice_range may not both be null"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("predicate column_names and slice_range may not both be null"); if (predicate.column_names != null && predicate.slice_range != null) - throw new InvalidRequestException("predicate column_names and slice_range may not both be present"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("predicate column_names and slice_range may not both be present"); if (predicate.getSlice_range() != null) validateRange(metadata, column_parent, predicate.slice_range); @@ -475,17 +449,17 @@ public class ThriftValidation validateColumnNames(metadata, column_parent, predicate.column_names); } - public static void validateKeyRange(CFMetaData metadata, ByteBuffer superColumn, KeyRange range) throws InvalidRequestException + public static void validateKeyRange(CFMetaData metadata, ByteBuffer superColumn, KeyRange range) throws org.apache.cassandra.exceptions.InvalidRequestException { if ((range.start_key == null) == (range.start_token == null) || (range.end_key == null) == (range.end_token == null)) { - throw new InvalidRequestException("exactly one of {start key, end key} or {start token, end token} must be specified"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("exactly one of {start key, end key} or {start token, end token} must be specified"); } // (key, token) is supported (for wide-row CFRR) but not (token, key) if (range.start_token != null && range.end_key != null) - throw new InvalidRequestException("start token + end key is not a supported key range"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("start token + end key is not a supported key range"); if (range.start_key != null && range.end_key != null) { @@ -495,9 +469,9 @@ public class ThriftValidation if (startToken.compareTo(endToken) > 0 && !endToken.isMinimum(p)) { if (p instanceof RandomPartitioner) - throw new InvalidRequestException("start key's md5 sorts after end key's md5. this is not allowed; you probably should not specify end key at all, under RandomPartitioner"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("start key's md5 sorts after end key's md5. this is not allowed; you probably should not specify end key at all, under RandomPartitioner"); else - throw new InvalidRequestException("start key must sort before (or equal to) finish key in your partitioner!"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("start key must sort before (or equal to) finish key in your partitioner!"); } } @@ -505,12 +479,12 @@ public class ThriftValidation if (!isEmpty(range.row_filter) && superColumn != null) { - throw new InvalidRequestException("super columns are not supported for indexing"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("super columns are not supported for indexing"); } if (range.count <= 0) { - throw new InvalidRequestException("maxRows must be positive"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("maxRows must be positive"); } } @@ -520,18 +494,18 @@ public class ThriftValidation } public static void validateIndexClauses(CFMetaData metadata, IndexClause index_clause) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { if (index_clause.expressions.isEmpty()) - throw new InvalidRequestException("index clause list may not be empty"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("index clause list may not be empty"); if (!validateFilterClauses(metadata, index_clause.expressions)) - throw new InvalidRequestException("No indexed columns present in index clause with operator EQ"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("No indexed columns present in index clause with operator EQ"); } // return true if index_clause contains an indexed columns with operator EQ public static boolean validateFilterClauses(CFMetaData metadata, List index_clause) - throws InvalidRequestException + throws org.apache.cassandra.exceptions.InvalidRequestException { if (isEmpty(index_clause)) // no filter to apply @@ -549,14 +523,14 @@ public class ThriftValidation } catch (MarshalException me) { - throw new InvalidRequestException(String.format("[%s]=[%s] failed name validation (%s)", - ByteBufferUtil.bytesToHex(expression.column_name), - ByteBufferUtil.bytesToHex(expression.value), - me.getMessage())); + throw new org.apache.cassandra.exceptions.InvalidRequestException(String.format("[%s]=[%s] failed name validation (%s)", + ByteBufferUtil.bytesToHex(expression.column_name), + ByteBufferUtil.bytesToHex(expression.value), + me.getMessage())); } if (expression.value.remaining() > 0xFFFF) - throw new InvalidRequestException("Index expression values may not be larger than 64K"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("Index expression values may not be larger than 64K"); AbstractType valueValidator = Schema.instance.getValueValidator(metadata.ksName, metadata.cfName, expression.column_name); try @@ -565,10 +539,10 @@ public class ThriftValidation } catch (MarshalException me) { - throw new InvalidRequestException(String.format("[%s]=[%s] failed value validation (%s)", - ByteBufferUtil.bytesToHex(expression.column_name), - ByteBufferUtil.bytesToHex(expression.value), - me.getMessage())); + throw new org.apache.cassandra.exceptions.InvalidRequestException(String.format("[%s]=[%s] failed value validation (%s)", + ByteBufferUtil.bytesToHex(expression.column_name), + ByteBufferUtil.bytesToHex(expression.value), + me.getMessage())); } isIndexed |= (expression.op == IndexOperator.EQ) && idxManager.indexes(expression.column_name); @@ -577,19 +551,7 @@ public class ThriftValidation return isIndexed; } - public static void validateCommutativeForWrite(CFMetaData metadata, ConsistencyLevel consistency) throws InvalidRequestException - { - if (consistency == ConsistencyLevel.ANY) - { - throw new InvalidRequestException("Consistency level ANY is not yet supported for counter columnfamily " + metadata.cfName); - } - else if (!metadata.getReplicateOnWrite() && consistency != ConsistencyLevel.ONE) - { - throw new InvalidRequestException("cannot achieve CL > CL.ONE without replicate_on_write on columnfamily " + metadata.cfName); - } - } - - public static void validateKeyspaceNotYetExisting(String newKsName) throws InvalidRequestException + public static void validateKeyspaceNotYetExisting(String newKsName) throws org.apache.cassandra.exceptions.InvalidRequestException { // keyspace names must be unique case-insensitively because the keyspace name becomes the directory // where we store CF sstables. Names that differ only in case would thus cause problems on @@ -597,16 +559,16 @@ public class ThriftValidation for (String ksName : Schema.instance.getTables()) { if (ksName.equalsIgnoreCase(newKsName)) - throw new InvalidRequestException(String.format("Keyspace names must be case-insensitively unique (\"%s\" conflicts with \"%s\")", - newKsName, - ksName)); + throw new org.apache.cassandra.exceptions.InvalidRequestException(String.format("Keyspace names must be case-insensitively unique (\"%s\" conflicts with \"%s\")", + newKsName, + ksName)); } } - public static void validateKeyspaceNotSystem(String modifiedKeyspace) throws InvalidRequestException + public static void validateKeyspaceNotSystem(String modifiedKeyspace) throws org.apache.cassandra.exceptions.InvalidRequestException { if (modifiedKeyspace.equalsIgnoreCase(Table.SYSTEM_KS)) - throw new InvalidRequestException("system keyspace is not user-modifiable"); + throw new org.apache.cassandra.exceptions.InvalidRequestException("system keyspace is not user-modifiable"); } public static IFilter asIFilter(SlicePredicate sp, AbstractType comparator) diff --git a/src/java/org/apache/cassandra/tools/NodeCmd.java b/src/java/org/apache/cassandra/tools/NodeCmd.java index 409716a117..3f3a62af04 100644 --- a/src/java/org/apache/cassandra/tools/NodeCmd.java +++ b/src/java/org/apache/cassandra/tools/NodeCmd.java @@ -34,7 +34,8 @@ import com.google.common.collect.Maps; import org.apache.commons.cli.*; import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutorMBean; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.db.Table; import org.apache.cassandra.db.compaction.CompactionManagerMBean; @@ -43,7 +44,6 @@ import org.apache.cassandra.locator.EndpointSnitchInfoMBean; import org.apache.cassandra.net.MessagingServiceMBean; import org.apache.cassandra.service.CacheServiceMBean; import org.apache.cassandra.service.StorageProxyMBean; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.EstimatedHistogram; import org.apache.cassandra.utils.Pair; @@ -1182,7 +1182,7 @@ public class NodeCmd } catch (InvalidRequestException e) { - err(e, e.getWhy()); + err(e, e.getMessage()); } } diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java index c3db63ce6f..814e6d169c 100644 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@ -37,7 +37,7 @@ import javax.management.remote.JMXServiceURL; import com.google.common.collect.Iterables; import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutorMBean; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.compaction.CompactionManagerMBean; @@ -49,8 +49,6 @@ import org.apache.cassandra.net.MessagingServiceMBean; import org.apache.cassandra.service.*; import org.apache.cassandra.streaming.StreamingService; import org.apache.cassandra.streaming.StreamingServiceMBean; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.UnavailableException; /** * JMX client operations for Cassandra. diff --git a/src/java/org/apache/cassandra/tools/SSTableExport.java b/src/java/org/apache/cassandra/tools/SSTableExport.java index 7017232ce3..260331ded4 100644 --- a/src/java/org/apache/cassandra/tools/SSTableExport.java +++ b/src/java/org/apache/cassandra/tools/SSTableExport.java @@ -40,7 +40,7 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.AbstractColumnContainer; diff --git a/src/java/org/apache/cassandra/tools/SSTableImport.java b/src/java/org/apache/cassandra/tools/SSTableImport.java index 0b116176f6..74a86caacf 100644 --- a/src/java/org/apache/cassandra/tools/SSTableImport.java +++ b/src/java/org/apache/cassandra/tools/SSTableImport.java @@ -35,7 +35,7 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.AbstractColumnContainer; diff --git a/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java b/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java index 626fb6e520..c1f033272e 100644 --- a/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java +++ b/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java @@ -20,7 +20,7 @@ package org.apache.cassandra.tools; import java.io.IOException; import java.io.PrintStream; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.sstable.Descriptor; import org.apache.cassandra.io.sstable.SSTableMetadata; diff --git a/src/java/org/apache/cassandra/tracing/Tracing.java b/src/java/org/apache/cassandra/tracing/Tracing.java index 7675d749fa..98a0cd41f2 100644 --- a/src/java/org/apache/cassandra/tracing/Tracing.java +++ b/src/java/org/apache/cassandra/tracing/Tracing.java @@ -34,6 +34,7 @@ import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.cql3.ColumnNameBuilder; import org.apache.cassandra.db.ColumnFamily; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.ExpiringColumn; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.db.marshal.InetAddressType; @@ -42,9 +43,6 @@ import org.apache.cassandra.db.marshal.TimeUUIDType; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.net.MessageIn; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.UUIDGen; @@ -177,7 +175,7 @@ public class Tracing StageManager.getStage(Stage.TRACING).execute(new WrappedRunnable() { - public void runMayThrow() throws TimedOutException, UnavailableException + public void runMayThrow() throws Exception { ColumnFamily cf = ColumnFamily.create(CFMetaData.TraceSessionsCf); addColumn(cf, @@ -212,7 +210,7 @@ public class Tracing StageManager.getStage(Stage.TRACING).execute(new WrappedRunnable() { - public void runMayThrow() throws TimedOutException, UnavailableException + public void runMayThrow() throws Exception { ColumnFamily cf = ColumnFamily.create(CFMetaData.TraceSessionsCf); addColumn(cf, diff --git a/src/java/org/apache/cassandra/tracing/TracingAppender.java b/src/java/org/apache/cassandra/tracing/TracingAppender.java index 3643adf05a..e0dcd07293 100644 --- a/src/java/org/apache/cassandra/tracing/TracingAppender.java +++ b/src/java/org/apache/cassandra/tracing/TracingAppender.java @@ -10,11 +10,9 @@ import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.db.ColumnFamily; +import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.RowMutation; import org.apache.cassandra.service.StorageProxy; -import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.UUIDGen; @@ -37,7 +35,7 @@ public class TracingAppender extends AppenderSkeleton final String threadName = event.getThreadName(); StageManager.getStage(Stage.TRACING).execute(new WrappedRunnable() { - public void runMayThrow() throws TimedOutException, UnavailableException + public void runMayThrow() throws Exception { ByteBuffer eventId = ByteBufferUtil.bytes(UUIDGen.makeType1UUIDFromHost(FBUtilities .getBroadcastAddress())); diff --git a/src/java/org/apache/cassandra/transport/DataType.java b/src/java/org/apache/cassandra/transport/DataType.java index 9a8c2f0283..29d7a931ad 100644 --- a/src/java/org/apache/cassandra/transport/DataType.java +++ b/src/java/org/apache/cassandra/transport/DataType.java @@ -26,7 +26,7 @@ import java.util.List; import com.google.common.base.Charsets; import org.jboss.netty.buffer.ChannelBuffer; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.db.marshal.*; import org.apache.cassandra.utils.Pair; @@ -188,7 +188,7 @@ public enum DataType implements OptionCodec.Codecable return entry.left.type; } } - catch (ConfigurationException e) + catch (RequestValidationException e) { throw new ProtocolException(e.getMessage()); } diff --git a/src/java/org/apache/cassandra/transport/ProtocolException.java b/src/java/org/apache/cassandra/transport/ProtocolException.java index 15112e1c4b..fd62581b07 100644 --- a/src/java/org/apache/cassandra/transport/ProtocolException.java +++ b/src/java/org/apache/cassandra/transport/ProtocolException.java @@ -17,13 +17,23 @@ */ package org.apache.cassandra.transport; +import java.nio.ByteBuffer; + +import org.apache.cassandra.exceptions.ExceptionCode; +import org.apache.cassandra.exceptions.TransportException; + /** - * Exceptions thrown when a client didn't not respect the protocol. + * Exceptions thrown when a client didn't respect the protocol. */ -public class ProtocolException extends RuntimeException +public class ProtocolException extends RuntimeException implements TransportException { public ProtocolException(String msg) { super(msg); } + + public ExceptionCode code() + { + return ExceptionCode.PROTOCOL_ERROR; + } } diff --git a/src/java/org/apache/cassandra/transport/ServerError.java b/src/java/org/apache/cassandra/transport/ServerError.java new file mode 100644 index 0000000000..55d5177908 --- /dev/null +++ b/src/java/org/apache/cassandra/transport/ServerError.java @@ -0,0 +1,44 @@ +/* + * 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.transport; + +import java.nio.ByteBuffer; + +import org.apache.cassandra.exceptions.ExceptionCode; +import org.apache.cassandra.exceptions.TransportException; + +/** + * Exceptions thrown when a client didn't respect the protocol. + */ +public class ServerError extends RuntimeException implements TransportException +{ + public ServerError(Throwable e) + { + super(e.toString()); + } + + public ServerError(String msg) + { + super(msg); + } + + public ExceptionCode code() + { + return ExceptionCode.SERVER_ERROR; + } +} diff --git a/src/java/org/apache/cassandra/transport/SimpleClient.java b/src/java/org/apache/cassandra/transport/SimpleClient.java index bca39ea36d..9e0ea2ec5f 100644 --- a/src/java/org/apache/cassandra/transport/SimpleClient.java +++ b/src/java/org/apache/cassandra/transport/SimpleClient.java @@ -154,7 +154,7 @@ public class SimpleClient lastWriteFuture = channel.write(request); Message.Response msg = responseHandler.responses.take(); if (msg instanceof ErrorMessage) - throw new RuntimeException(((ErrorMessage)msg).errorMsg); + throw new RuntimeException((Throwable)((ErrorMessage)msg).error); return msg; } catch (InterruptedException e) diff --git a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java index 7204f971e9..c21e727ec1 100644 --- a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java @@ -17,77 +17,161 @@ */ package org.apache.cassandra.transport.messages; +import java.nio.ByteBuffer; import java.util.concurrent.TimeoutException; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.exceptions.*; import org.apache.cassandra.transport.CBUtil; import org.apache.cassandra.transport.Message; import org.apache.cassandra.transport.ProtocolException; +import org.apache.cassandra.transport.ServerError; import org.apache.cassandra.thrift.AuthenticationException; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.utils.ByteBufferUtil; /** * Message to indicate an error to the client. - * - * Error codes are: - * 0x0000: Server error - * 0x0001: Protocol error - * 0x0002: Authentication error - * 0x0100: Unavailable exception - * 0x0101: Timeout exception - * 0x0200: Request exception */ public class ErrorMessage extends Message.Response { + private static final Logger logger = LoggerFactory.getLogger(ErrorMessage.class); + public static final Message.Codec codec = new Message.Codec() { public ErrorMessage decode(ChannelBuffer body) { - int code = body.readInt(); + ExceptionCode code = ExceptionCode.fromValue(body.readInt()); String msg = CBUtil.readString(body); - return new ErrorMessage(code, msg); + + TransportException te = null; + switch (code) + { + case SERVER_ERROR: + te = new ServerError(msg); + break; + case PROTOCOL_ERROR: + te = new ProtocolException(msg); + break; + case UNAVAILABLE: + { + ConsistencyLevel cl = Enum.valueOf(ConsistencyLevel.class, CBUtil.readString(body)); + int required = body.readInt(); + int alive = body.readInt(); + te = new UnavailableException(cl, required, alive); + } + break; + case OVERLOADED: + te = new OverloadedException(msg); + break; + case IS_BOOTSTRAPPING: + te = new IsBootstrappingException(); + break; + case TRUNCATE_ERROR: + te = new TruncateException(msg); + break; + case WRITE_TIMEOUT: + { + ConsistencyLevel cl = Enum.valueOf(ConsistencyLevel.class, CBUtil.readString(body)); + int received = body.readInt(); + int blockFor = body.readInt(); + te = new WriteTimeoutException(cl, received, blockFor); + } + break; + case READ_TIMEOUT: + { + ConsistencyLevel cl = Enum.valueOf(ConsistencyLevel.class, CBUtil.readString(body)); + int received = body.readInt(); + int blockFor = body.readInt(); + byte dataPresent = body.readByte(); + te = new ReadTimeoutException(cl, received, blockFor, dataPresent != 0); + } + break; + case SYNTAX_ERROR: + te = new SyntaxException(msg); + break; + case UNAUTHORIZED: + te = new UnauthorizedException(msg); + break; + case INVALID: + te = new InvalidRequestException(msg); + break; + case CONFIG_ERROR: + te = new ConfigurationException(msg); + break; + case ALREADY_EXISTS: + String ksName = CBUtil.readString(body); + String cfName = CBUtil.readString(body); + te = new AlreadyExistsException(ksName, cfName); + break; + } + return new ErrorMessage(te); } public ChannelBuffer encode(ErrorMessage msg) { - ChannelBuffer ccb = CBUtil.intToCB(msg.code); - ChannelBuffer mcb = CBUtil.stringToCB(msg.errorMsg); - return ChannelBuffers.wrappedBuffer(ccb, mcb); + ChannelBuffer ccb = CBUtil.intToCB(msg.error.code().value); + ChannelBuffer mcb = CBUtil.stringToCB(msg.error.getMessage()); + + ChannelBuffer acb = ChannelBuffers.EMPTY_BUFFER; + switch (msg.error.code()) + { + case UNAVAILABLE: + UnavailableException ue = (UnavailableException)msg.error; + ByteBuffer ueCl = ByteBufferUtil.bytes(ue.consistency.toString()); + + acb = ChannelBuffers.buffer(2 + ueCl.remaining() + 8); + acb.writeShort((short)ueCl.remaining()); + acb.writeBytes(ueCl); + acb.writeInt(ue.required); + acb.writeInt(ue.alive); + break; + case WRITE_TIMEOUT: + case READ_TIMEOUT: + RequestTimeoutException rte = (RequestTimeoutException)msg.error; + ReadTimeoutException readEx = rte instanceof ReadTimeoutException + ? (ReadTimeoutException)rte + : null; + ByteBuffer rteCl = ByteBufferUtil.bytes(rte.consistency.toString()); + acb = ChannelBuffers.buffer(2 + rteCl.remaining() + 8 + (readEx == null ? 0 : 1)); + acb.writeShort((short)rteCl.remaining()); + acb.writeBytes(rteCl); + acb.writeInt(rte.received); + acb.writeInt(rte.blockFor); + if (readEx != null) + acb.writeByte((byte)(readEx.dataPresent ? 1 : 0)); + break; + case ALREADY_EXISTS: + AlreadyExistsException aee = (AlreadyExistsException)msg.error; + acb = ChannelBuffers.wrappedBuffer(CBUtil.stringToCB(aee.ksName), + CBUtil.stringToCB(aee.cfName)); + break; + } + return ChannelBuffers.wrappedBuffer(ccb, mcb, acb); } }; // We need to figure error codes out (#3979) - public final int code; - public final String errorMsg; + public final TransportException error; - public ErrorMessage(int code, String errorMsg) + private ErrorMessage(TransportException error) { super(Message.Type.ERROR); - this.code = code; - this.errorMsg = errorMsg; + this.error = error; } - public static ErrorMessage fromException(Throwable t) + public static ErrorMessage fromException(Throwable e) { - String msg = t.getMessage() == null ? t.toString() : t.getMessage(); + if (e instanceof TransportException) + return new ErrorMessage((TransportException)e); - if (t instanceof TimeoutException || t instanceof TimedOutException) - return new ErrorMessage(0x0101, msg); - else if (t instanceof UnavailableException) - return new ErrorMessage(0x0100, msg); - else if (t instanceof InvalidRequestException) - return new ErrorMessage(0x0200, msg); - else if (t instanceof ProtocolException) - return new ErrorMessage(0x0001, msg); - else if (t instanceof AuthenticationException) - return new ErrorMessage(0x0002, msg); - - logger.error("Unknown exception during request", t); - return new ErrorMessage(0x0000, msg); + // Unexpected exception + logger.debug("Unexpected exception during request", e); + return new ErrorMessage(new ServerError(e)); } public ChannelBuffer encode() @@ -98,6 +182,6 @@ public class ErrorMessage extends Message.Response @Override public String toString() { - return "ERROR " + code + ": " + errorMsg; + return "ERROR " + error.code() + ": " + error.getMessage(); } } diff --git a/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java b/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java index e93b58c47d..9d2d0e4957 100644 --- a/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java @@ -25,8 +25,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.apache.cassandra.cql3.CQLStatement; import org.apache.cassandra.cql3.QueryProcessor; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.transport.*; -import org.apache.cassandra.thrift.InvalidRequestException; public class ExecuteMessage extends Message.Request { diff --git a/src/java/org/apache/cassandra/transport/messages/QueryMessage.java b/src/java/org/apache/cassandra/transport/messages/QueryMessage.java index 2aefcb8aa8..399fe959b7 100644 --- a/src/java/org/apache/cassandra/transport/messages/QueryMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/QueryMessage.java @@ -20,10 +20,10 @@ package org.apache.cassandra.transport.messages; import org.jboss.netty.buffer.ChannelBuffer; import org.apache.cassandra.cql3.QueryProcessor; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestTimeoutException; +import org.apache.cassandra.exceptions.UnavailableException; import org.apache.cassandra.transport.*; -import org.apache.cassandra.thrift.InvalidRequestException; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; /** * A CQL query @@ -67,7 +67,7 @@ public class QueryMessage extends Message.Request { if (!((e instanceof UnavailableException) || (e instanceof InvalidRequestException) - || (e instanceof TimedOutException))) + || (e instanceof RequestTimeoutException))) { logger.error("Unexpected error during query", e); } diff --git a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java index a8fe43b038..fc28b69bf9 100644 --- a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java @@ -24,8 +24,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.transport.*; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.SemanticVersion; /** @@ -133,12 +133,12 @@ public class StartupMessage extends Message.Request if (compression.equals("snappy")) { if (FrameCompressor.SnappyCompressor.instance == null) - throw new InvalidRequestException("This instance does not support Snappy compression"); + throw new ProtocolException("This instance does not support Snappy compression"); connection.setCompressor(FrameCompressor.SnappyCompressor.instance); } else { - throw new InvalidRequestException(String.format("Unknown compression algorithm: %s", compression)); + throw new ProtocolException(String.format("Unknown compression algorithm: %s", compression)); } } @@ -149,7 +149,7 @@ public class StartupMessage extends Message.Request } catch (InvalidRequestException e) { - return ErrorMessage.fromException(e); + return ErrorMessage.fromException(new ProtocolException(e.getMessage())); } } diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java index fcfdd2b952..c7c73560f6 100644 --- a/src/java/org/apache/cassandra/utils/FBUtilities.java +++ b/src/java/org/apache/cassandra/utils/FBUtilities.java @@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.cache.IRowCacheProvider; import org.apache.cassandra.concurrent.CreationTimeAwareFuture; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.dht.IPartitioner; diff --git a/test/long/org/apache/cassandra/db/MeteredFlusherTest.java b/test/long/org/apache/cassandra/db/MeteredFlusherTest.java index ba2d2fdf98..e2a6973b16 100644 --- a/test/long/org/apache/cassandra/db/MeteredFlusherTest.java +++ b/test/long/org/apache/cassandra/db/MeteredFlusherTest.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.utils.ByteBufferUtil; diff --git a/test/unit/org/apache/cassandra/SchemaLoader.java b/test/unit/org/apache/cassandra/SchemaLoader.java index 51898351af..2197b2b0e9 100644 --- a/test/unit/org/apache/cassandra/SchemaLoader.java +++ b/test/unit/org/apache/cassandra/SchemaLoader.java @@ -36,6 +36,7 @@ import org.apache.cassandra.db.compaction.LeveledCompactionStrategy; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.index.composites.CompositesIndex; import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.Gossiper; import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.io.compress.SnappyCompressor; diff --git a/test/unit/org/apache/cassandra/cli/CliTest.java b/test/unit/org/apache/cassandra/cli/CliTest.java index c13cf01ae7..989e40076b 100644 --- a/test/unit/org/apache/cassandra/cli/CliTest.java +++ b/test/unit/org/apache/cassandra/cli/CliTest.java @@ -19,7 +19,7 @@ package org.apache.cassandra.cli; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.Schema; import org.apache.cassandra.service.EmbeddedCassandraService; import org.apache.cassandra.thrift.*; diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java index 99fc58dadd..4273662794 100644 --- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java +++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java @@ -19,10 +19,11 @@ package org.apache.cassandra.config; import org.apache.cassandra.SchemaLoader; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.gms.Gossiper; import org.apache.cassandra.locator.SimpleStrategy; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.thrift.InvalidRequestException; import org.junit.Test; diff --git a/test/unit/org/apache/cassandra/config/DefsTest.java b/test/unit/org/apache/cassandra/config/DefsTest.java index b01ffc4885..5bb16a0b3d 100644 --- a/test/unit/org/apache/cassandra/config/DefsTest.java +++ b/test/unit/org/apache/cassandra/config/DefsTest.java @@ -32,6 +32,7 @@ import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.BytesType; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.db.marshal.TimeUUIDType; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.io.sstable.Component; import org.apache.cassandra.io.sstable.Descriptor; import org.apache.cassandra.io.sstable.SSTableDeletingTask; diff --git a/test/unit/org/apache/cassandra/db/CleanupTest.java b/test/unit/org/apache/cassandra/db/CleanupTest.java index ec74ae3578..85eb70be34 100644 --- a/test/unit/org/apache/cassandra/db/CleanupTest.java +++ b/test/unit/org/apache/cassandra/db/CleanupTest.java @@ -29,7 +29,7 @@ import java.util.concurrent.ExecutionException; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.columniterator.IdentityQueryFilter; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.filter.IFilter; diff --git a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java index 090aad3f9a..f8dafc4f6c 100644 --- a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java +++ b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java @@ -56,7 +56,7 @@ import static org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.columniterator.IdentityQueryFilter; import org.apache.cassandra.db.filter.*; import org.apache.cassandra.db.index.SecondaryIndex; diff --git a/test/unit/org/apache/cassandra/db/ScrubTest.java b/test/unit/org/apache/cassandra/db/ScrubTest.java index 871723e6d6..fbde9088d3 100644 --- a/test/unit/org/apache/cassandra/db/ScrubTest.java +++ b/test/unit/org/apache/cassandra/db/ScrubTest.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.columniterator.IdentityQueryFilter; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.io.util.FileUtils; diff --git a/test/unit/org/apache/cassandra/db/SecondaryIndexColumnSizeTest.java b/test/unit/org/apache/cassandra/db/SecondaryIndexColumnSizeTest.java index 00bd7791dd..e1cce4ec25 100644 --- a/test/unit/org/apache/cassandra/db/SecondaryIndexColumnSizeTest.java +++ b/test/unit/org/apache/cassandra/db/SecondaryIndexColumnSizeTest.java @@ -25,7 +25,7 @@ import java.util.SortedSet; import org.junit.Test; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.index.PerColumnSecondaryIndex; import org.apache.cassandra.db.index.PerRowSecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexSearcher; diff --git a/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java b/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java index 1bc3d7099c..dd07d840b0 100644 --- a/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java +++ b/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java @@ -29,7 +29,8 @@ import static org.junit.Assert.fail; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryFilter; import org.apache.cassandra.db.filter.QueryPath; @@ -200,6 +201,7 @@ public class CompositeTypeTest extends SchemaLoader fail("Shouldn't work"); } catch (ConfigurationException e) {} + catch (SyntaxException e) {} try { @@ -207,6 +209,7 @@ public class CompositeTypeTest extends SchemaLoader fail("Shouldn't work"); } catch (ConfigurationException e) {} + catch (SyntaxException e) {} } @Test diff --git a/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java b/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java index dc7037a72b..ee3052c17a 100644 --- a/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java +++ b/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java @@ -21,12 +21,13 @@ package org.apache.cassandra.db.marshal; import org.junit.Test; import static org.junit.Assert.fail; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; public class TypeParserTest { @Test - public void testParse() throws ConfigurationException + public void testParse() throws ConfigurationException, SyntaxException { AbstractType type; @@ -61,7 +62,7 @@ public class TypeParserTest } @Test - public void testParseError() throws ConfigurationException + public void testParseError() { try { @@ -69,6 +70,7 @@ public class TypeParserTest fail("Should not pass"); } catch (ConfigurationException e) {} + catch (SyntaxException e) {} try { @@ -76,5 +78,6 @@ public class TypeParserTest fail("Should not pass"); } catch (ConfigurationException e) {} + catch (SyntaxException e) {} } } diff --git a/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java b/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java index 21a799386e..298f1c7bb4 100644 --- a/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java +++ b/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java @@ -23,7 +23,7 @@ import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.service.StorageService; import org.junit.Test; diff --git a/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java b/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java index 103db51b58..db79a739f9 100644 --- a/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java +++ b/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java @@ -27,7 +27,7 @@ import java.io.IOException; import java.net.InetAddress; import java.util.Map; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.gms.ApplicationState; import org.apache.cassandra.gms.Gossiper; import org.apache.cassandra.gms.VersionedValue; diff --git a/test/unit/org/apache/cassandra/locator/NetworkTopologyStrategyTest.java b/test/unit/org/apache/cassandra/locator/NetworkTopologyStrategyTest.java index a120f200ec..6de0b0980c 100644 --- a/test/unit/org/apache/cassandra/locator/NetworkTopologyStrategyTest.java +++ b/test/unit/org/apache/cassandra/locator/NetworkTopologyStrategyTest.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.dht.StringToken; import org.apache.cassandra.dht.Token; diff --git a/test/unit/org/apache/cassandra/locator/ReplicationStrategyEndpointCacheTest.java b/test/unit/org/apache/cassandra/locator/ReplicationStrategyEndpointCacheTest.java index 33dc4cc4c1..bbb382b6ef 100644 --- a/test/unit/org/apache/cassandra/locator/ReplicationStrategyEndpointCacheTest.java +++ b/test/unit/org/apache/cassandra/locator/ReplicationStrategyEndpointCacheTest.java @@ -28,7 +28,7 @@ import org.apache.commons.lang.StringUtils; import org.junit.Test; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.BigIntegerToken; import org.apache.cassandra.dht.Token; diff --git a/test/unit/org/apache/cassandra/locator/SimpleStrategyTest.java b/test/unit/org/apache/cassandra/locator/SimpleStrategyTest.java index 8c17f6d27e..5f108eefc5 100644 --- a/test/unit/org/apache/cassandra/locator/SimpleStrategyTest.java +++ b/test/unit/org/apache/cassandra/locator/SimpleStrategyTest.java @@ -30,7 +30,7 @@ import org.apache.cassandra.config.Schema; import org.junit.Test; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.KSMetaData; import org.apache.cassandra.db.Table; import org.apache.cassandra.dht.*; diff --git a/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java b/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java index af876fc289..ec0dffc8c3 100644 --- a/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java +++ b/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java @@ -26,7 +26,7 @@ import java.util.LinkedList; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.utils.ByteBufferUtil; -import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.db.ConsistencyLevel; public class AntiEntropyServiceCounterTest extends AntiEntropyServiceTestAbstract { diff --git a/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java b/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java index 332f95ad5c..a70c7c0ad4 100644 --- a/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java +++ b/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java @@ -26,7 +26,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.thrift.*; diff --git a/test/unit/org/apache/cassandra/service/InitClientTest.java b/test/unit/org/apache/cassandra/service/InitClientTest.java index a248ca723a..7d44cd8f6f 100644 --- a/test/unit/org/apache/cassandra/service/InitClientTest.java +++ b/test/unit/org/apache/cassandra/service/InitClientTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import java.io.IOException; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; /** * Licensed to the Apache Software Foundation (ASF) under one diff --git a/test/unit/org/apache/cassandra/service/LeaveAndBootstrapTest.java b/test/unit/org/apache/cassandra/service/LeaveAndBootstrapTest.java index 7e2130c0f2..73abbe2f12 100644 --- a/test/unit/org/apache/cassandra/service/LeaveAndBootstrapTest.java +++ b/test/unit/org/apache/cassandra/service/LeaveAndBootstrapTest.java @@ -24,7 +24,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.Schema; import org.junit.Test; diff --git a/test/unit/org/apache/cassandra/service/MoveTest.java b/test/unit/org/apache/cassandra/service/MoveTest.java index ce7864cc87..65d934b9aa 100644 --- a/test/unit/org/apache/cassandra/service/MoveTest.java +++ b/test/unit/org/apache/cassandra/service/MoveTest.java @@ -33,7 +33,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.Schema; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; diff --git a/test/unit/org/apache/cassandra/service/RemoveTest.java b/test/unit/org/apache/cassandra/service/RemoveTest.java index 58ae797bb1..4e21a7b190 100644 --- a/test/unit/org/apache/cassandra/service/RemoveTest.java +++ b/test/unit/org/apache/cassandra/service/RemoveTest.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.RandomPartitioner; import org.apache.cassandra.dht.Token; diff --git a/test/unit/org/apache/cassandra/service/StorageServiceClientTest.java b/test/unit/org/apache/cassandra/service/StorageServiceClientTest.java index e0dca35123..19efe3a175 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceClientTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceClientTest.java @@ -20,7 +20,7 @@ package org.apache.cassandra.service; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.junit.Test; import static org.junit.Assert.assertFalse; diff --git a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java index e43124d3e8..c4931a6df0 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java @@ -26,7 +26,7 @@ import java.util.List; import org.junit.Test; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.db.Table; import org.apache.cassandra.dht.Token; import org.apache.cassandra.SchemaLoader; diff --git a/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java index 41b432e4a7..45ab7485ce 100644 --- a/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java +++ b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java @@ -28,20 +28,21 @@ import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.*; import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.locator.LocalStrategy; import org.apache.cassandra.locator.NetworkTopologyStrategy; import org.apache.cassandra.utils.ByteBufferUtil; public class ThriftValidationTest extends SchemaLoader { - @Test(expected=InvalidRequestException.class) - public void testValidateCommutativeWithStandard() throws InvalidRequestException + @Test(expected=org.apache.cassandra.exceptions.InvalidRequestException.class) + public void testValidateCommutativeWithStandard() throws org.apache.cassandra.exceptions.InvalidRequestException { ThriftValidation.validateColumnFamily("Keyspace1", "Standard1", true); } @Test - public void testValidateCommutativeWithCounter() throws InvalidRequestException + public void testValidateCommutativeWithCounter() throws org.apache.cassandra.exceptions.InvalidRequestException { ThriftValidation.validateColumnFamily("Keyspace1", "Counter1", true); } diff --git a/tools/stress/src/org/apache/cassandra/stress/Session.java b/tools/stress/src/org/apache/cassandra/stress/Session.java index 5763f37532..9fff0439e3 100644 --- a/tools/stress/src/org/apache/cassandra/stress/Session.java +++ b/tools/stress/src/org/apache/cassandra/stress/Session.java @@ -26,7 +26,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.db.marshal.*; import org.apache.commons.cli.*; @@ -142,7 +143,7 @@ public class Session implements Serializable public final boolean timeUUIDComparator; public double traceProbability = 0.0; - public Session(String[] arguments) throws IllegalArgumentException + public Session(String[] arguments) throws IllegalArgumentException, SyntaxException { float STDev = 0.1f; CommandLineParser parser = new PosixParser();