From fa1d99ac96a0939b6ca811c0edc0f25da6075464 Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Mon, 31 Aug 2009 15:50:58 +0000 Subject: [PATCH] add forwards-compatible ConsistencyLevel parameter to get_key_range. Currently it is a no-op. patch by Chris Goffinet; reviewed by jbellis for CASSANDRA-322 git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@809639 13f79535-47bb-0310-9956-ffa450edef68 --- interface/cassandra.thrift | 2 +- .../apache/cassandra/service/Cassandra.java | 118 ++++++++++++++++-- .../cassandra/service/CassandraServer.java | 2 +- test/system/test_server.py | 24 ++-- 4 files changed, 125 insertions(+), 21 deletions(-) diff --git a/interface/cassandra.thrift b/interface/cassandra.thrift index fdd6900ffd..86e846039e 100644 --- a/interface/cassandra.thrift +++ b/interface/cassandra.thrift @@ -139,7 +139,7 @@ service Cassandra { throws (1: InvalidRequestException ire, 2: UnavailableException ue), # range query: returns matching keys - list get_key_range(1:string keyspace, 2:string column_family, 3:string start="", 4:string finish="", 5:i32 count=100) + list get_key_range(1:string keyspace, 2:string column_family, 3:string start="", 4:string finish="", 5:i32 count=100, 6:ConsistencyLevel consistency_level=1) throws (1: InvalidRequestException ire), ///////////////////////////////////////////////////////////////////////////////////// diff --git a/interface/gen-java/org/apache/cassandra/service/Cassandra.java b/interface/gen-java/org/apache/cassandra/service/Cassandra.java index f70bdcfd8b..35ac4b9ee4 100644 --- a/interface/gen-java/org/apache/cassandra/service/Cassandra.java +++ b/interface/gen-java/org/apache/cassandra/service/Cassandra.java @@ -61,7 +61,7 @@ public class Cassandra { public void remove(String keyspace, String key, ColumnPath column_path, long timestamp, int consistency_level) throws InvalidRequestException, UnavailableException, TException; - public List get_key_range(String keyspace, String column_family, String start, String finish, int count) throws InvalidRequestException, TException; + public List get_key_range(String keyspace, String column_family, String start, String finish, int count, int consistency_level) throws InvalidRequestException, TException; public String get_string_property(String property) throws TException; @@ -420,13 +420,13 @@ public class Cassandra { return; } - public List get_key_range(String keyspace, String column_family, String start, String finish, int count) throws InvalidRequestException, TException + public List get_key_range(String keyspace, String column_family, String start, String finish, int count, int consistency_level) throws InvalidRequestException, TException { - send_get_key_range(keyspace, column_family, start, finish, count); + send_get_key_range(keyspace, column_family, start, finish, count, consistency_level); return recv_get_key_range(); } - public void send_get_key_range(String keyspace, String column_family, String start, String finish, int count) throws TException + public void send_get_key_range(String keyspace, String column_family, String start, String finish, int count, int consistency_level) throws TException { oprot_.writeMessageBegin(new TMessage("get_key_range", TMessageType.CALL, seqid_)); get_key_range_args args = new get_key_range_args(); @@ -435,6 +435,7 @@ public class Cassandra { args.start = start; args.finish = finish; args.count = count; + args.consistency_level = consistency_level; args.write(oprot_); oprot_.writeMessageEnd(); oprot_.getTransport().flush(); @@ -850,7 +851,7 @@ public class Cassandra { iprot.readMessageEnd(); get_key_range_result result = new get_key_range_result(); try { - result.success = iface_.get_key_range(args.keyspace, args.column_family, args.start, args.finish, args.count); + result.success = iface_.get_key_range(args.keyspace, args.column_family, args.start, args.finish, args.count, args.consistency_level); } catch (InvalidRequestException ire) { result.ire = ire; } catch (Throwable th) { @@ -7841,6 +7842,7 @@ public class Cassandra { private static final TField START_FIELD_DESC = new TField("start", TType.STRING, (short)3); private static final TField FINISH_FIELD_DESC = new TField("finish", TType.STRING, (short)4); private static final TField COUNT_FIELD_DESC = new TField("count", TType.I32, (short)5); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)6); public String keyspace; public static final int KEYSPACE = 1; @@ -7852,10 +7854,17 @@ public class Cassandra { public static final int FINISH = 4; public int count; public static final int COUNT = 5; + /** + * + * @see ConsistencyLevel + */ + public int consistency_level; + public static final int CONSISTENCY_LEVEL = 6; // isset id assignments private static final int __COUNT_ISSET_ID = 0; - private BitSet __isset_bit_vector = new BitSet(1); + private static final int __CONSISTENCY_LEVEL_ISSET_ID = 1; + private BitSet __isset_bit_vector = new BitSet(2); public static final Map metaDataMap = Collections.unmodifiableMap(new HashMap() {{ put(KEYSPACE, new FieldMetaData("keyspace", TFieldRequirementType.DEFAULT, @@ -7868,6 +7877,8 @@ public class Cassandra { new FieldValueMetaData(TType.STRING))); put(COUNT, new FieldMetaData("count", TFieldRequirementType.DEFAULT, new FieldValueMetaData(TType.I32))); + put(CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.I32))); }}); static { @@ -7881,6 +7892,8 @@ public class Cassandra { this.count = 100; + this.consistency_level = 1; + } public get_key_range_args( @@ -7888,7 +7901,8 @@ public class Cassandra { String column_family, String start, String finish, - int count) + int count, + int consistency_level) { this(); this.keyspace = keyspace; @@ -7897,6 +7911,8 @@ public class Cassandra { this.finish = finish; this.count = count; setCountIsSet(true); + this.consistency_level = consistency_level; + setConsistency_levelIsSet(true); } /** @@ -7918,6 +7934,7 @@ public class Cassandra { this.finish = other.finish; } this.count = other.count; + this.consistency_level = other.consistency_level; } @Override @@ -8044,6 +8061,37 @@ public class Cassandra { __isset_bit_vector.set(__COUNT_ISSET_ID, value); } + /** + * + * @see ConsistencyLevel + */ + public int getConsistency_level() { + return this.consistency_level; + } + + /** + * + * @see ConsistencyLevel + */ + public get_key_range_args setConsistency_level(int consistency_level) { + this.consistency_level = consistency_level; + setConsistency_levelIsSet(true); + return this; + } + + public void unsetConsistency_level() { + __isset_bit_vector.clear(__CONSISTENCY_LEVEL_ISSET_ID); + } + + // Returns true if field consistency_level is set (has been asigned a value) and false otherwise + public boolean isSetConsistency_level() { + return __isset_bit_vector.get(__CONSISTENCY_LEVEL_ISSET_ID); + } + + public void setConsistency_levelIsSet(boolean value) { + __isset_bit_vector.set(__CONSISTENCY_LEVEL_ISSET_ID, value); + } + public void setFieldValue(int fieldID, Object value) { switch (fieldID) { case KEYSPACE: @@ -8086,6 +8134,14 @@ public class Cassandra { } break; + case CONSISTENCY_LEVEL: + if (value == null) { + unsetConsistency_level(); + } else { + setConsistency_level((Integer)value); + } + break; + default: throw new IllegalArgumentException("Field " + fieldID + " doesn't exist!"); } @@ -8108,6 +8164,9 @@ public class Cassandra { case COUNT: return new Integer(getCount()); + case CONSISTENCY_LEVEL: + return getConsistency_level(); + default: throw new IllegalArgumentException("Field " + fieldID + " doesn't exist!"); } @@ -8126,6 +8185,8 @@ public class Cassandra { return isSetFinish(); case COUNT: return isSetCount(); + case CONSISTENCY_LEVEL: + return isSetConsistency_level(); default: throw new IllegalArgumentException("Field " + fieldID + " doesn't exist!"); } @@ -8189,6 +8250,15 @@ public class Cassandra { return false; } + boolean this_present_consistency_level = true; + boolean that_present_consistency_level = true; + if (this_present_consistency_level || that_present_consistency_level) { + if (!(this_present_consistency_level && that_present_consistency_level)) + return false; + if (this.consistency_level != that.consistency_level) + return false; + } + return true; } @@ -8245,6 +8315,14 @@ public class Cassandra { if (lastComparison != 0) { return lastComparison; } + lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(isSetConsistency_level()); + if (lastComparison != 0) { + return lastComparison; + } + lastComparison = TBaseHelper.compareTo(consistency_level, typedOther.consistency_level); + if (lastComparison != 0) { + return lastComparison; + } return 0; } @@ -8295,6 +8373,14 @@ public class Cassandra { TProtocolUtil.skip(iprot, field.type); } break; + case CONSISTENCY_LEVEL: + if (field.type == TType.I32) { + this.consistency_level = iprot.readI32(); + setConsistency_levelIsSet(true); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; default: TProtocolUtil.skip(iprot, field.type); break; @@ -8335,6 +8421,9 @@ public class Cassandra { oprot.writeFieldBegin(COUNT_FIELD_DESC); oprot.writeI32(this.count); oprot.writeFieldEnd(); + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level); + oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -8379,6 +8468,18 @@ public class Cassandra { sb.append("count:"); sb.append(this.count); first = false; + if (!first) sb.append(", "); + sb.append("consistency_level:"); + String consistency_level_name = ConsistencyLevel.VALUES_TO_NAMES.get(this.consistency_level); + if (consistency_level_name != null) { + sb.append(consistency_level_name); + sb.append(" ("); + } + sb.append(this.consistency_level); + if (consistency_level_name != null) { + sb.append(")"); + } + first = false; sb.append(")"); return sb.toString(); } @@ -8386,6 +8487,9 @@ public class Cassandra { public void validate() throws TException { // check for required fields // check that fields of type enum have valid values + if (isSetConsistency_level() && !ConsistencyLevel.VALID_VALUES.contains(consistency_level)){ + throw new TProtocolException("The field 'consistency_level' has been assigned the invalid value " + consistency_level); + } } } diff --git a/src/java/org/apache/cassandra/service/CassandraServer.java b/src/java/org/apache/cassandra/service/CassandraServer.java index dde38ba0e8..293dd02d9b 100644 --- a/src/java/org/apache/cassandra/service/CassandraServer.java +++ b/src/java/org/apache/cassandra/service/CassandraServer.java @@ -576,7 +576,7 @@ public class CassandraServer implements Cassandra.Iface return columnFamiliesMap; } - public List get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException + public List get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults, int consistency_level) throws InvalidRequestException, TException { if (logger.isDebugEnabled()) logger.debug("get_key_range"); diff --git a/test/system/test_server.py b/test/system/test_server.py index deb2f61e0b..ddd1408095 100644 --- a/test/system/test_server.py +++ b/test/system/test_server.py @@ -284,7 +284,7 @@ class TestMutations(CassandraTester): # get doesn't specify supercolumn name _expect_exception(lambda: client.get('Keyspace1', 'key1', ColumnPath('Super1'), ConsistencyLevel.ONE), InvalidRequestException) # invalid CF - _expect_exception(lambda: client.get_key_range('Keyspace1', 'S', '', '', 1000), InvalidRequestException) + _expect_exception(lambda: client.get_key_range('Keyspace1', 'S', '', '', 1000, ConsistencyLevel.ONE), InvalidRequestException) # 'x' is not a valid Long _expect_exception(lambda: client.insert('Keyspace1', 'key1', ColumnPath('Super1', 'sc1', 'x'), 'value', 0, ConsistencyLevel.ONE), InvalidRequestException) # start is not a valid Long @@ -440,31 +440,31 @@ class TestMutations(CassandraTester): def test_empty_range(self): - assert client.get_key_range('Keyspace1', 'Standard1', '', '', 1000) == [] + assert client.get_key_range('Keyspace1', 'Standard1', '', '', 1000, ConsistencyLevel.ONE) == [] _insert_simple() - assert client.get_key_range('Keyspace1', 'Super1', '', '', 1000) == [] + assert client.get_key_range('Keyspace1', 'Super1', '', '', 1000, ConsistencyLevel.ONE) == [] def test_range_with_remove(self): _insert_simple() - assert client.get_key_range('Keyspace1', 'Standard1', 'key1', '', 1000) == ['key1'] + assert client.get_key_range('Keyspace1', 'Standard1', 'key1', '', 1000, ConsistencyLevel.ONE) == ['key1'] client.remove('Keyspace1', 'key1', ColumnPath('Standard1', column='c1'), 1, ConsistencyLevel.ONE) client.remove('Keyspace1', 'key1', ColumnPath('Standard1', column='c2'), 1, ConsistencyLevel.ONE) - actual = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000) + actual = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000, ConsistencyLevel.ONE) assert actual == [], actual def test_range_with_remove_cf(self): _insert_simple() - assert client.get_key_range('Keyspace1', 'Standard1', 'key1', '', 1000) == ['key1'] + assert client.get_key_range('Keyspace1', 'Standard1', 'key1', '', 1000, ConsistencyLevel.ONE) == ['key1'] client.remove('Keyspace1', 'key1', ColumnPath('Standard1'), 1, ConsistencyLevel.ONE) - actual = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000) + actual = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000, ConsistencyLevel.ONE) assert actual == [], actual def test_range_collation(self): for key in ['-a', '-b', 'a', 'b'] + [str(i) for i in xrange(100)]: client.insert('Keyspace1', key, ColumnPath('Standard1', column=key), 'v', 0, ConsistencyLevel.ONE) - L = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000) + L = client.get_key_range('Keyspace1', 'Standard1', '', '', 1000, ConsistencyLevel.ONE) # note the collated ordering rather than ascii assert L == ['0', '1', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22', '23', '24', '25', '26', '27','28', '29', '3', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '4', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '8', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '9', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', 'a', '-a', 'b', '-b'], L @@ -472,16 +472,16 @@ class TestMutations(CassandraTester): for key in ['-a', '-b', 'a', 'b'] + [str(i) for i in xrange(100)]: client.insert('Keyspace1', key, ColumnPath('Standard1', column=key), 'v', 0, ConsistencyLevel.ONE) - L = client.get_key_range('Keyspace1', 'Standard1', 'a', '', 1000) + L = client.get_key_range('Keyspace1', 'Standard1', 'a', '', 1000, ConsistencyLevel.ONE) assert L == ['a', '-a', 'b', '-b'], L - L = client.get_key_range('Keyspace1', 'Standard1', '', '15', 1000) + L = client.get_key_range('Keyspace1', 'Standard1', '', '15', 1000, ConsistencyLevel.ONE) assert L == ['0', '1', '10', '11', '12', '13', '14', '15'], L - L = client.get_key_range('Keyspace1', 'Standard1', '50', '51', 1000) + L = client.get_key_range('Keyspace1', 'Standard1', '50', '51', 1000, ConsistencyLevel.ONE) assert L == ['50', '51'], L - L = client.get_key_range('Keyspace1', 'Standard1', '1', '', 10) + L = client.get_key_range('Keyspace1', 'Standard1', '1', '', 10, ConsistencyLevel.ONE) assert L == ['1', '10', '11', '12', '13', '14', '15', '16', '17', '18'], L def test_get_slice_range(self):