From 921f4994f3197b77774c75fd84fa806139561ba0 Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Tue, 10 May 2011 19:03:58 +0000 Subject: [PATCH] merge from 0.8 git-svn-id: https://svn.apache.org/repos/asf/cassandra/branches/cassandra-0.8.1@1101598 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 5 ++-- NEWS.txt | 7 ++--- .../cassandra/cql/jdbc/ColumnDecoder.java | 3 +- .../apache/cassandra/config/CFMetaData.java | 2 +- .../apache/cassandra/config/KSMetaData.java | 28 +++++++++++++++---- .../apache/cassandra/cql/QueryProcessor.java | 10 ++++--- .../locator/AbstractReplicationStrategy.java | 15 ++++++++++ .../locator/NetworkTopologyStrategy.java | 8 ++---- .../locator/OldNetworkTopologyStrategy.java | 14 ++-------- .../cassandra/locator/SimpleStrategy.java | 12 ++------ .../cassandra/thrift/CassandraServer.java | 23 ++++----------- .../cassandra/thrift/ThriftValidation.java | 4 +-- .../org/apache/cassandra/cli/CliHelp.yaml | 2 +- 13 files changed, 67 insertions(+), 66 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c8f7b2a2da18..7e21dbede9a7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -27,6 +27,8 @@ * r/m clustertool (CASSANDRA-2607) * add support for presenting row key as a column in CQL result sets (CASSANDRA-2622) + * Don't allow {LOCAL|EACH}_QUORUM unless strategy is NTS (CASSANDRA-2627) + * validate keyspace strategy_options during CQL create (CASSANDRA-2624) 0.8.0-beta2 @@ -54,12 +56,11 @@ * improve ignoring of obsolete mutations in index maintenance (CASSANDRA-2401) * recognize attempt to drop just the index while leaving the column definition alone (CASSANDRA-2619) - * Don't allow {LOCAL|EACH}_QUORUM unless strategy is NTS (CASSANDRA-2627) 0.8.0-beta1 * remove Avro RPC support (CASSANDRA-926) - * adds support for columns that act as incr/decr counters + * support for columns that act as incr/decr counters (CASSANDRA-1072, 1937, 1944, 1936, 2101, 2093, 2288, 2105, 2384, 2236, 2342, 2454) * CQL (CASSANDRA-1703, 1704, 1705, 1706, 1707, 1708, 1710, 1711, 1940, diff --git a/NEWS.txt b/NEWS.txt index 8a4a64e79332..4f7bcff88719 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -5,19 +5,18 @@ Upgrading --------- - Upgrading from version 0.7.1 or later can be done with a rolling restart, one node at a time. You do not need to bring down the - whole cluster. + whole cluster at once. - Running nodetool drain before shutting down the 0.7 node is recommended but not required. (Skipping this will result in replay of entire commitlog, so it will take longer to restart but is otherwise harmless.) + - 0.8 is fully API-compatible with 0.7. You can continue + to use your 0.7 clients. - Avro record classes used in map/reduce and Hadoop streaming code have moved from org.apache.cassandra.avro to org.apache.cassandra.hadoop.avro, applications using these classes will need to be updated accordingly. - The loadbalance command has been removed from nodetool. For similar behavior, decommission then rebootstrap with empty initial_token. - - repair now works on a token range, rather than the entire ring. This - means that "run repair against each node" will now repair the ring with - no redundant work. Features -------- diff --git a/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java b/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java index 606bb1bcbd84..7d8663b1d762 100644 --- a/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java +++ b/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java @@ -28,7 +28,6 @@ import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.thrift.*; import org.apache.cassandra.utils.ByteBufferUtil; -import org.apache.cassandra.utils.FBUtilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +58,7 @@ public ColumnDecoder(List defs) { try { - metadata.put(String.format("%s.%s", ks.getName(), cf.getName()), CFMetaData.convertToCFMetaData(cf)); + metadata.put(String.format("%s.%s", ks.getName(), cf.getName()), CFMetaData.fromThrift(cf)); } catch (InvalidRequestException e) { diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java index 3042b3da9e23..48090b166ee7 100644 --- a/src/java/org/apache/cassandra/config/CFMetaData.java +++ b/src/java/org/apache/cassandra/config/CFMetaData.java @@ -629,7 +629,7 @@ public static void applyImplicitDefaults(org.apache.cassandra.thrift.CfDef cf_de cf_def.setRow_cache_provider(CFMetaData.DEFAULT_ROW_CACHE_PROVIDER); } - public static CFMetaData convertToCFMetaData(org.apache.cassandra.thrift.CfDef cf_def) throws InvalidRequestException, ConfigurationException + public static CFMetaData fromThrift(org.apache.cassandra.thrift.CfDef cf_def) throws InvalidRequestException, ConfigurationException { ColumnFamilyType cfType = ColumnFamilyType.create(cf_def.column_type); if (cfType == null) diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java index cb6887869255..fdb9e5648c73 100644 --- a/src/java/org/apache/cassandra/config/KSMetaData.java +++ b/src/java/org/apache/cassandra/config/KSMetaData.java @@ -18,10 +18,7 @@ package org.apache.cassandra.config; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import java.util.*; import org.apache.commons.lang.ObjectUtils; @@ -29,6 +26,7 @@ import org.apache.cassandra.io.SerDeUtils; import org.apache.cassandra.locator.AbstractReplicationStrategy; import org.apache.cassandra.locator.NetworkTopologyStrategy; +import org.apache.cassandra.thrift.CfDef; import org.apache.cassandra.thrift.KsDef; import org.apache.commons.lang.StringUtils; @@ -51,7 +49,7 @@ public KSMetaData(String name, Class stra this.cfMetaData = Collections.unmodifiableMap(cfmap); } - public static Map backwardsCompatibleOptions(KsDef ks_def) + public static Map forwardsCompatibleOptions(KsDef ks_def) { Map options; if (ks_def.isSetReplication_factor()) @@ -165,4 +163,24 @@ public static Map optsWithRF(final Integer rf) ret.put("replication_factor", rf.toString()); return ret; } + + public static KSMetaData fromThrift(KsDef ksd, CFMetaData... cfDefs) throws ConfigurationException + { + return new KSMetaData(ksd.name, + AbstractReplicationStrategy.getClass(ksd.strategy_class), + forwardsCompatibleOptions(ksd), + cfDefs); + } + + public static KsDef toThrift(KSMetaData ksm) + { + List cfDefs = new ArrayList(); + for (CFMetaData cfm : ksm.cfMetaData().values()) + cfDefs.add(CFMetaData.convertToThrift(cfm)); + KsDef ksdef = new KsDef(ksm.name, ksm.strategyClass.getName(), cfDefs); + ksdef.setStrategy_options(ksm.strategyOptions); + if (ksm.strategyOptions != null && ksm.strategyOptions.containsKey("replication_factor")) + ksdef.setReplication_factor(Integer.parseInt(ksm.strategyOptions.get("replication_factor"))); + return ksdef; + } } diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java b/src/java/org/apache/cassandra/cql/QueryProcessor.java index 24ded313b990..8ca6f0bb84ba 100644 --- a/src/java/org/apache/cassandra/cql/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java @@ -638,10 +638,12 @@ public static CqlResult process(String queryString, ClientState clientState) try { - KSMetaData ksm = new KSMetaData(create.getName(), - AbstractReplicationStrategy.getClass(create.getStrategyClass()), - create.getStrategyOptions()); - applyMigrationOnStage(new AddKeyspace(ksm)); + KsDef ksd = new KsDef(create.getName(), + create.getStrategyClass(), + Collections.emptyList()) + .setStrategy_options(create.getStrategyOptions()); + ThriftValidation.validateKsDef(ksd); + applyMigrationOnStage(new AddKeyspace(KSMetaData.fromThrift(ksd))); } catch (ConfigurationException e) { diff --git a/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java b/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java index 9c931f193622..0532b86f106a 100644 --- a/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java +++ b/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java @@ -289,4 +289,19 @@ public static Class getClass(String cls) throws Con String className = cls.contains(".") ? cls : "org.apache.cassandra.locator." + cls; return FBUtilities.classForName(className, "replication strategy"); } + + protected void validateReplicationFactor(String rf) throws ConfigurationException + { + try + { + if (Integer.parseInt(rf) < 0) + { + throw new ConfigurationException("Replication factor must be non-negative; found " + rf); + } + } + catch (NumberFormatException e2) + { + throw new ConfigurationException("Replication factor must be numeric; found " + rf); + } + } } diff --git a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java index 2f5b59ecd7b9..67e02e633470 100644 --- a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java +++ b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java @@ -146,13 +146,9 @@ public Set getDatacenters() public void validateOptions() throws ConfigurationException { - for (Entry e : this.configOptions.entrySet()) + for (Entry e : this.configOptions.entrySet()) { - int rf = Integer.parseInt(e.getValue()); - if (rf < 0) - { - throw new ConfigurationException("Replication factor for NTS must be non-negative. dc: " +e.getKey()+", rf: "+rf); - } + validateReplicationFactor(e.getValue()); } } diff --git a/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java b/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java index f35a6cd6e22f..558d6599ff15 100644 --- a/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java +++ b/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java @@ -111,18 +111,10 @@ public int getReplicationFactor() public void validateOptions() throws ConfigurationException { - if (this.configOptions == null) + if (configOptions == null || configOptions.get("replication_factor") == null) { - throw new ConfigurationException("OldNetworkTopologyStrategy requires a replication_factor strategy option."); - } - if (this.configOptions.get("replication_factor") == null) - { - throw new ConfigurationException("OldNetworkTopologyStrategy requires a replication_factor strategy option."); - } - int rf = Integer.parseInt(this.configOptions.get("replication_factor")); - if (rf < 0) - { - throw new ConfigurationException("Replication factor for OldNetworkTopologyStrategy must be non-negative, "+rf+" given."); + throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option."); } + validateReplicationFactor(configOptions.get("replication_factor")); } } diff --git a/src/java/org/apache/cassandra/locator/SimpleStrategy.java b/src/java/org/apache/cassandra/locator/SimpleStrategy.java index dccae562f435..09935df2cbfd 100644 --- a/src/java/org/apache/cassandra/locator/SimpleStrategy.java +++ b/src/java/org/apache/cassandra/locator/SimpleStrategy.java @@ -70,18 +70,10 @@ public int getReplicationFactor() public void validateOptions() throws ConfigurationException { - if (this.configOptions == null) + if (configOptions == null || configOptions.get("replication_factor") == null) { throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option."); } - if (this.configOptions.get("replication_factor") == null) - { - throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option."); - } - int rf = Integer.parseInt(this.configOptions.get("replication_factor")); - if (rf < 0) - { - throw new ConfigurationException("Replication factor for SimpleStrategy must be non-negative, "+rf+" given."); - } + validateReplicationFactor(configOptions.get("replication_factor")); } } diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java index 46a804731996..ac6074e3fb80 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraServer.java +++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java @@ -578,12 +578,7 @@ public KsDef describe_keyspace(String table) throws NotFoundException, InvalidRe if (ksm == null) throw new NotFoundException(); - List cfDefs = new ArrayList(); - for (CFMetaData cfm : ksm.cfMetaData().values()) - cfDefs.add(CFMetaData.convertToThrift(cfm)); - KsDef ksdef = new KsDef(ksm.name, ksm.strategyClass.getName(), cfDefs); - ksdef.setStrategy_options(ksm.strategyOptions); - return ksdef; + return KSMetaData.toThrift(ksm); } public List get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level) @@ -809,7 +804,7 @@ public synchronized String system_add_column_family(CfDef cf_def) try { - applyMigrationOnStage(new AddColumnFamily(CFMetaData.convertToCFMetaData(cf_def))); + applyMigrationOnStage(new AddColumnFamily(CFMetaData.fromThrift(cf_def))); return DatabaseDescriptor.getDefsVersion().toString(); } catch (ConfigurationException e) @@ -874,16 +869,11 @@ public synchronized String system_add_keyspace(KsDef ks_def) for (CfDef cfDef : ks_def.cf_defs) { ThriftValidation.validateCfDef(cfDef); - cfDefs.add(CFMetaData.convertToCFMetaData(cfDef)); + cfDefs.add(CFMetaData.fromThrift(cfDef)); } ThriftValidation.validateKsDef(ks_def); - KSMetaData ksm = new KSMetaData(ks_def.name, - AbstractReplicationStrategy.getClass(ks_def.strategy_class), - KSMetaData.backwardsCompatibleOptions(ks_def), - cfDefs.toArray(new CFMetaData[cfDefs.size()])); - - applyMigrationOnStage(new AddKeyspace(ksm)); + applyMigrationOnStage(new AddKeyspace(KSMetaData.fromThrift(ks_def, cfDefs.toArray(new CFMetaData[cfDefs.size()])))); return DatabaseDescriptor.getDefsVersion().toString(); } catch (ConfigurationException e) @@ -941,10 +931,7 @@ public synchronized String system_update_keyspace(KsDef ks_def) try { ThriftValidation.validateKsDef(ks_def); - KSMetaData ksm = new KSMetaData(ks_def.name, - AbstractReplicationStrategy.getClass(ks_def.strategy_class), - KSMetaData.backwardsCompatibleOptions(ks_def)); - applyMigrationOnStage(new UpdateKeyspace(ksm)); + applyMigrationOnStage(new UpdateKeyspace(KSMetaData.fromThrift(ks_def))); return DatabaseDescriptor.getDefsVersion().toString(); } catch (ConfigurationException e) diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java b/src/java/org/apache/cassandra/thrift/ThriftValidation.java index 35e042b09543..69e79b837d66 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java +++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java @@ -591,11 +591,11 @@ public static void validateCommutativeForWrite(CFMetaData metadata, ConsistencyL } } - static void validateKsDef(KsDef ks_def) throws ConfigurationException + public static void validateKsDef(KsDef ks_def) throws ConfigurationException { // Attempt to instantiate the ARS, which will throw a ConfigException if // the strategy_options aren't fully formed or if the ARS Classname is invalid. - Map options = KSMetaData.backwardsCompatibleOptions(ks_def); + Map options = KSMetaData.forwardsCompatibleOptions(ks_def); TokenMetadata tmd = StorageService.instance.getTokenMetadata(); IEndpointSnitch eps = DatabaseDescriptor.getEndpointSnitch(); Class cls = AbstractReplicationStrategy.getClass(ks_def.strategy_class); diff --git a/src/resources/org/apache/cassandra/cli/CliHelp.yaml b/src/resources/org/apache/cassandra/cli/CliHelp.yaml index 64dcfaa20570..95924edeb3ed 100644 --- a/src/resources/org/apache/cassandra/cli/CliHelp.yaml +++ b/src/resources/org/apache/cassandra/cli/CliHelp.yaml @@ -391,7 +391,7 @@ commands: It is also valid to specify the fully-qualified class name to a class that extends org.apache.Cassandra.db.marshal.AbstractType. - - key_valiation_class: Validator to use for keys. + - key_validation_class: Validator to use for keys. Default is BytesType which applies no validation. Supported values are: