Author: gdusbabek
Date: Fri Sep 3 20:24:59 2010
New Revision: 992453
URL: http://svn.apache.org/viewvc?rev=992453&view=rev
Log:
UpdateColumn family. patch by gdusbabek, reviewed by stuhood. CASSANDRA-1285
Added:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
Modified:
cassandra/trunk/src/avro/internode.genavro
cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
cassandra/trunk/test/system/test_thrift_server.py
cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
Modified: cassandra/trunk/src/avro/internode.genavro
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/avro/internode.genavro?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/src/avro/internode.genavro (original)
+++ cassandra/trunk/src/avro/internode.genavro Fri Sep 3 20:24:59 2010
@@ -113,6 +113,12 @@ protocol InterNode {
org.apache.cassandra.config.avro.KsDef oldKs;
org.apache.cassandra.config.avro.KsDef newKs;
}
+
+ @namespace("org.apache.cassandra.db.migration.avro")
+ record UpdateColumnFamily {
+ org.apache.cassandra.config.avro.CfDef oldCf;
+ org.apache.cassandra.config.avro.CfDef newCf;
+ }
@namespace("org.apache.cassandra.db.migration.avro")
record Migration {
@@ -120,6 +126,6 @@ protocol InterNode {
org.apache.cassandra.utils.avro.UUID new_version;
bytes row_mutation;
string classname;
- union {
AddColumnFamily,DropColumnFamily,RenameColumnFamily,AddKeyspace,DropKeyspace,RenameKeyspace,UpdateKeyspace
} migration;
+ union {
AddColumnFamily,DropColumnFamily,RenameColumnFamily,AddKeyspace,DropKeyspace,RenameKeyspace,UpdateKeyspace,UpdateColumnFamily
} migration;
}
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Fri
Sep 3 20:24:59 2010
@@ -18,12 +18,14 @@
package org.apache.cassandra.config;
+import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.collect.*;
import org.apache.avro.util.Utf8;
+import org.apache.cassandra.config.avro.CfDef;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -94,14 +96,6 @@ public final class CFMetaData
}
/**
- * @return An immutable mapping of id to (ksname,cfname).
- */
- public static final Map<Integer, Pair<String, String>> getIdToCfMap()
- {
- return Collections.unmodifiableMap(cfIdMap.inverse());
- }
-
- /**
* @return The (ksname,cfname) pair for the given id, or null if it has
been dropped.
*/
public static final Pair<String,String> getCF(Integer cfId)
@@ -124,6 +118,7 @@ public final class CFMetaData
idGen.set(cfIdMap.size() == 0 ? MIN_CF_ID :
Math.max(Collections.max(cfIdMap.values()) + 1, MIN_CF_ID));
}
+ public final Integer cfId;
public final String tableName; // name of table which has this
column family
public final String cfName; // name of the column family
public final ColumnFamilyType cfType; // type: super, standard, etc.
@@ -135,10 +130,10 @@ public final class CFMetaData
public final double rowCacheSize; // default 0
public final double keyCacheSize; // default 0.01
public final double readRepairChance; //chance 0 to 1, of doing a read
repair; defaults 1.0 (always)
- public final Integer cfId;
- public boolean preloadRowCache;
+ public final boolean preloadRowCache;
public final int gcGraceSeconds; // default 864000 (ten days)
public final AbstractType defaultValidator; // values are longs, strings,
bytes (no-op)...
+ // NOTE: if you find yourself adding members to this class, make sure you
keep the convert methods in lockstep.
public final Map<byte[], ColumnDefinition> column_metadata;
@@ -342,4 +337,82 @@ public final class CFMetaData
validator = columnDefinition.validator;
return validator;
}
+
+ // merges some final fields from this CFM with modifiable fields from
CfDef into a new CFMetaData.
+ public CFMetaData apply(org.apache.cassandra.thrift.CfDef cf_def) throws
ConfigurationException
+ {
+ // validate
+ if (cf_def.id != cfId)
+ throw new ConfigurationException("ids do not match.");
+ if (!cf_def.keyspace.equals(tableName))
+ throw new ConfigurationException("keyspaces do not match.");
+ if (!cf_def.name.equals(cfName))
+ throw new ConfigurationException("names do not match.");
+ if (!cf_def.column_type.equals(cfType.name()))
+ throw new ConfigurationException("types do not match.");
+ if (!cf_def.clock_type.equals(clockType.name()))
+ throw new ConfigurationException("clock types do not match.");
+ if (comparator !=
DatabaseDescriptor.getComparator(cf_def.comparator_type))
+ throw new ConfigurationException("comparators do not match.");
+ if (cf_def.subcomparator_type == null ||
cf_def.subcomparator_type.equals(""))
+ {
+ if (subcolumnComparator != null)
+ throw new ConfigurationException("subcolumncomparators do not
match.");
+ // else, it's null and we're good.
+ }
+ else if (subcolumnComparator !=
DatabaseDescriptor.getComparator(cf_def.subcomparator_type))
+ throw new ConfigurationException("subcolumncomparators do not
match.");
+
+ return new CFMetaData(tableName,
+ cfName,
+ cfType,
+ clockType,
+ comparator,
+ subcolumnComparator,
+ reconciler,
+ cf_def.comment,
+ cf_def.row_cache_size,
+ cf_def.preload_row_cache,
+ cf_def.key_cache_size,
+ cf_def.read_repair_chance,
+ cf_def.gc_grace_seconds,
+
DatabaseDescriptor.getComparator(cf_def.default_validation_class == null ? null
: cf_def.default_validation_class),
+ cfId,
+ column_metadata);
+ }
+
+ // converts CFM to thrift CfDef
+ public static org.apache.cassandra.thrift.CfDef convertToThrift(CFMetaData
cfm)
+ {
+ org.apache.cassandra.thrift.CfDef def = new
org.apache.cassandra.thrift.CfDef(cfm.tableName, cfm.cfName);
+ def.setId(cfm.cfId);
+ def.setColumn_type(cfm.cfType.name());
+ def.setClock_type(cfm.clockType.name());
+ def.setComparator_type(cfm.comparator.getClass().getName());
+ if (cfm.subcolumnComparator != null)
+ {
+
def.setSubcomparator_type(cfm.subcolumnComparator.getClass().getName());
+ def.setColumn_type("Super");
+ }
+ def.setReconciler(cfm.reconciler == null ? "" :
cfm.reconciler.getClass().getName());
+ def.setComment(cfm.comment == null ? "" : cfm.comment);
+ def.setRow_cache_size(cfm.rowCacheSize);
+ def.setPreload_row_cache(cfm.preloadRowCache);
+ def.setKey_cache_size(cfm.keyCacheSize);
+ def.setRead_repair_chance(cfm.readRepairChance);
+ def.setGc_grace_seconds(cfm.gcGraceSeconds);
+
def.setDefault_validation_class(cfm.defaultValidator.getClass().getName());
+ List< org.apache.cassandra.thrift.ColumnDef> column_meta = new
ArrayList< org.apache.cassandra.thrift.ColumnDef>();
+ for (ColumnDefinition cd : cfm.column_metadata.values())
+ {
+ org.apache.cassandra.thrift.ColumnDef tcd = new
org.apache.cassandra.thrift.ColumnDef();
+ tcd.setIndex_name(cd.index_name);
+ tcd.setIndex_type(cd.index_type);
+ tcd.setName(cd.name);
+ tcd.setValidation_class(cd.validator.getClass().getName());
+ column_meta.add(tcd);
+ }
+ def.setColumn_metadata(column_meta);
+ return def;
+ }
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/Table.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Fri Sep 3
20:24:59 2010
@@ -301,6 +301,14 @@ public class Table
columnFamilyStores.put(cfId,
ColumnFamilyStore.createColumnFamilyStore(name, cfName));
}
+ public void reloadCf(Integer cfId) throws IOException
+ {
+ ColumnFamilyStore cfs = columnFamilyStores.remove(cfId);
+ assert cfs != null;
+ unloadCf(cfs);
+ initCf(cfId, cfs.getColumnFamilyName());
+ }
+
/** basically a combined drop and add */
public void renameCf(Integer cfId, String newName) throws IOException
{
Added:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java?rev=992453&view=auto
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
(added)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java
Fri Sep 3 20:24:59 2010
@@ -0,0 +1,103 @@
+package org.apache.cassandra.db.migration;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.ConfigurationException;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.config.KSMetaData;
+import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.db.Table;
+import org.apache.cassandra.utils.FBUtilities;
+import org.apache.cassandra.utils.UUIDGen;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+
+/** todo: doesn't work with secondary indices yet. See CASSANDRA-1415. */
+public class UpdateColumnFamily extends Migration
+{
+ private CFMetaData oldCfm;
+ private CFMetaData newCfm;
+
+ protected UpdateColumnFamily() { }
+
+ /** assumes validation has already happened. That is, replacing oldCfm
with newCfm is neither illegal or totally whackass. */
+ public UpdateColumnFamily(CFMetaData oldCfm, CFMetaData newCfm) throws
ConfigurationException, IOException
+ {
+ super(UUIDGen.makeType1UUIDFromHost(FBUtilities.getLocalAddress()),
DatabaseDescriptor.getDefsVersion());
+
+ KSMetaData ksm =
DatabaseDescriptor.getTableDefinition(newCfm.tableName);
+ if (ksm == null)
+ throw new ConfigurationException("Keyspace does not already
exist.");
+
+ this.oldCfm = oldCfm;
+ this.newCfm = newCfm;
+
+ // we'll allow this eventually.
+ if (!oldCfm.column_metadata.equals(newCfm.column_metadata))
+ throw new ConfigurationException("Column meta information is not
identical.");
+
+ // clone ksm but include the new cf def.
+ KSMetaData newKsm = makeNewKeyspaceDefinition(ksm);
+ rm = Migration.makeDefinitionMutation(newKsm, null, newVersion);
+ }
+
+ private KSMetaData makeNewKeyspaceDefinition(KSMetaData ksm)
+ {
+ List<CFMetaData> newCfs = new
ArrayList<CFMetaData>(ksm.cfMetaData().values());
+ newCfs.remove(oldCfm);
+ newCfs.add(newCfm);
+ return new KSMetaData(ksm.name, ksm.strategyClass,
ksm.strategyOptions, ksm.replicationFactor, newCfs.toArray(new
CFMetaData[newCfs.size()]));
+ }
+
+ public void beforeApplyModels()
+ {
+ if (clientMode)
+ return;
+ ColumnFamilyStore cfs =
Table.open(oldCfm.tableName).getColumnFamilyStore(oldCfm.cfName);
+ cfs.snapshot(Table.getTimestampedSnapshotName(null));
+ }
+
+ void applyModels() throws IOException
+ {
+ // all we really need to do is reload the cfstore.
+ KSMetaData newKsm =
makeNewKeyspaceDefinition(DatabaseDescriptor.getTableDefinition(newCfm.tableName));
+ DatabaseDescriptor.setTableDefinition(newKsm, newVersion);
+
+ if (!clientMode)
+ Table.open(oldCfm.tableName).reloadCf(newCfm.cfId);
+ }
+
+ public void subdeflate(org.apache.cassandra.db.migration.avro.Migration mi)
+ {
+ org.apache.cassandra.db.migration.avro.UpdateColumnFamily update = new
org.apache.cassandra.db.migration.avro.UpdateColumnFamily();
+ update.newCf = newCfm.deflate();
+ update.oldCf = oldCfm.deflate();
+ mi.migration = update;
+ }
+
+ public void subinflate(org.apache.cassandra.db.migration.avro.Migration mi)
+ {
+ org.apache.cassandra.db.migration.avro.UpdateColumnFamily update =
(org.apache.cassandra.db.migration.avro.UpdateColumnFamily)mi.migration;
+ newCfm = CFMetaData.inflate(update.newCf);
+ oldCfm = CFMetaData.inflate(update.oldCf);
+ }
+}
Modified:
cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
Fri Sep 3 20:24:59 2010
@@ -26,6 +26,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import org.apache.cassandra.db.migration.Migration;
+import org.apache.cassandra.db.migration.UpdateColumnFamily;
import org.apache.cassandra.db.migration.UpdateKeyspace;
import org.apache.cassandra.utils.FBUtilities;
import org.slf4j.Logger;
@@ -457,27 +458,7 @@ public class CassandraServer implements
List<CfDef> cfDefs = new ArrayList<CfDef>();
for (CFMetaData cfm : ksm.cfMetaData().values())
- {
- CfDef def = new CfDef(cfm.tableName, cfm.cfName);
- if (cfm.subcolumnComparator != null)
- {
-
def.setSubcomparator_type(cfm.subcolumnComparator.getClass().getName());
- def.setColumn_type("Super");
- }
- def.setComparator_type(cfm.comparator.getClass().getName());
-
- List<ColumnDef> cdef_list = new ArrayList<ColumnDef>();
- for (ColumnDefinition col_definition :
cfm.column_metadata.values())
- {
- ColumnDef cdef = new ColumnDef(col_definition.name,
col_definition.validator.getClass().getName());
- cdef.setIndex_name(col_definition.index_name);
- cdef.setIndex_type(col_definition.index_type);
- cdef_list.add(cdef);
- }
-
- def.setColumn_metadata(cdef_list);
- cfDefs.add(def);
- }
+ cfDefs.add(CFMetaData.convertToThrift(cfm));
return new KsDef(ksm.name, ksm.strategyClass.getName(),
ksm.replicationFactor, cfDefs);
}
@@ -869,7 +850,7 @@ public class CassandraServer implements
/** update an existing keyspace, but do not allow column family
modifications. */
public String system_update_keyspace(KsDef ks_def) throws
InvalidRequestException, TException
{
- checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+ clientState.hasKeyspaceAccess(Permission.WRITE);
if (ks_def.getCf_defs() != null && ks_def.getCf_defs().size() > 0)
throw new InvalidRequestException("Keyspace update must not
contain any column family definitions.");
@@ -905,8 +886,34 @@ public class CassandraServer implements
public String system_update_column_family(CfDef cf_def) throws
InvalidRequestException, TException
{
- checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
- return null;
+ clientState.hasKeyspaceAccess(Permission.WRITE);
+
+ if (cf_def.keyspace == null || cf_def.name == null)
+ throw new InvalidRequestException("Keyspace and CF name must be
set.");
+
+ CFMetaData oldCfm =
DatabaseDescriptor.getCFMetaData(CFMetaData.getId(cf_def.keyspace,
cf_def.name));
+ if (oldCfm == null)
+ throw new InvalidRequestException("Could not find column family
definition to modify.");
+
+ try
+ {
+ CFMetaData newCfm = oldCfm.apply(cf_def);
+ UpdateColumnFamily update = new UpdateColumnFamily(oldCfm, newCfm);
+ applyMigrationOnStage(update);
+ return DatabaseDescriptor.getDefsVersion().toString();
+ }
+ catch (ConfigurationException e)
+ {
+ InvalidRequestException ex = new
InvalidRequestException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch (IOException e)
+ {
+ InvalidRequestException ex = new
InvalidRequestException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ }
}
private CFMetaData convertToCFMetaData(CfDef cf_def) throws
InvalidRequestException, ConfigurationException
Modified: cassandra/trunk/test/system/test_thrift_server.py
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_thrift_server.py?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_thrift_server.py (original)
+++ cassandra/trunk/test/system/test_thrift_server.py Fri Sep 3 20:24:59 2010
@@ -1260,6 +1260,27 @@ class TestMutations(ThriftTester):
client.system_add_column_family(newcf)
ks1 = client.describe_keyspace('Keyspace1')
assert 'NewColumnFamily' in [x.name for x in ks1.cf_defs]
+ cfid = [x.id for x in ks1.cf_defs if x.name=='NewColumnFamily'][0]
+ assert cfid > 1000
+
+ # modify invalid
+ modified_cf = CfDef('Keyspace1', 'NewColumnFamily',
column_metadata=[cd])
+ modified_cf.id = cfid
+ def fail_invalid_field():
+ modified_cf.comparator_type = 'LongType'
+ client.system_update_column_family(modified_cf)
+ _expect_exception(fail_invalid_field, InvalidRequestException)
+
+ # modify valid
+ modified_cf.comparator_type = 'BytesType' # revert back to old value.
+ modified_cf.row_cache_size = 25
+ modified_cf.gc_grace_seconds = 1
+ client.system_update_column_family(modified_cf)
+ ks1 = client.describe_keyspace('Keyspace1')
+ server_cf = [x for x in ks1.cf_defs if x.name=='NewColumnFamily'][0]
+ assert server_cf
+ assert server_cf.row_cache_size == 25
+ assert server_cf.gc_grace_seconds == 1
# rename
client.system_rename_column_family('NewColumnFamily',
'RenameColumnFamily')
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java?rev=992453&r1=992452&r2=992453&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Fri Sep 3
20:24:59 2010
@@ -23,7 +23,10 @@ import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutionException;
+import org.apache.cassandra.io.SerDeUtils;
import org.apache.cassandra.locator.OldNetworkTopologyStrategy;
+import org.apache.cassandra.thrift.CfDef;
+import org.apache.cassandra.thrift.ColumnDef;
import org.junit.Test;
import org.apache.cassandra.CleanupHelper;
@@ -506,4 +509,142 @@ public class DefsTest extends CleanupHel
assert newFetchedKs.strategyClass.equals(newKs.strategyClass);
assert !newFetchedKs.strategyClass.equals(oldKs.strategyClass);
}
+
+ @Test
+ public void testUpdateColumnFamilyNoIndexes() throws
ConfigurationException, IOException, ExecutionException, InterruptedException
+ {
+ // create a keyspace with a cf to update.
+ CFMetaData cf = new CFMetaData("UpdatedCfKs", "Standard1added",
ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null,
TimestampReconciler.instance, "A new cf that will be updated", 0, false, 1.0,
0, 864000, BytesType.instance, Collections.<byte[],
ColumnDefinition>emptyMap());
+ KSMetaData ksm = new KSMetaData(cf.tableName, SimpleStrategy.class,
null, 1, cf);
+ new AddKeyspace(ksm).apply();
+
+ assert DatabaseDescriptor.getTableDefinition(cf.tableName) != null;
+ assert DatabaseDescriptor.getTableDefinition(cf.tableName) == ksm;
+
+ // updating certain fields should fail.
+ CfDef cf_def = new CfDef();
+ cf_def.setId(cf.cfId);
+ cf_def.setKeyspace(cf.tableName);
+ cf_def.setName(cf.cfName);
+ cf_def.setColumn_type(cf.cfType.name());
+ cf_def.setClock_type(cf.clockType.name());
+ cf_def.setComment(cf.comment);
+ cf_def.setComparator_type(cf.comparator.getClass().getName());
+ cf_def.setSubcomparator_type(null);
+ cf_def.setGc_grace_seconds(cf.gcGraceSeconds);
+ cf_def.setKey_cache_size(cf.keyCacheSize);
+ cf_def.setPreload_row_cache(cf.preloadRowCache);
+ cf_def.setRead_repair_chance(cf.readRepairChance);
+ cf_def.setRow_cache_size(43.3);
+ cf_def.setColumn_metadata(new ArrayList<ColumnDef>());
+
cf_def.setReconciler("org.apache.cassandra.db.clock.TimestampReconciiler");
+ cf_def.setDefault_validation_class("BytesType");
+
+ // test valid operations.
+ cf_def.setComment("Modified comment");
+ CFMetaData updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setRow_cache_size(2d);
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setKey_cache_size(3d);
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setRead_repair_chance(0.23);
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setGc_grace_seconds(12);
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setPreload_row_cache(!cf_def.preload_row_cache);
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ cf_def.setDefault_validation_class("UTF8Type");
+ updateCfm = cf.apply(cf_def);
+ new UpdateColumnFamily(cf, updateCfm).apply();
+ cf = updateCfm;
+
+ // can't test changing the reconciler because there is only one impl.
+
+ // check the cumulative affect.
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).comment.equals(cf_def.comment);
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).rowCacheSize == cf_def.row_cache_size;
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).keyCacheSize == cf_def.key_cache_size;
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).readRepairChance == cf_def.read_repair_chance;
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).gcGraceSeconds == cf_def.gc_grace_seconds;
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).preloadRowCache == cf_def.preload_row_cache;
+ assert DatabaseDescriptor.getCFMetaData(cf.tableName,
cf.cfName).defaultValidator == UTF8Type.instance;
+
+ // make sure some invalid operations fail.
+ int oldId = cf_def.id;
+ try
+ {
+ cf_def.setId(cf_def.getId() + 1);
+ updateCfm = cf.apply(cf_def);
+ throw new AssertionError("Should have blown up when you used a
different id.");
+ }
+ catch (ConfigurationException expected)
+ {
+ cf_def.setId(oldId);
+ }
+
+ String oldStr = cf_def.getName();
+ try
+ {
+ cf_def.setName(cf_def.getName() + "_renamed");
+ updateCfm = cf.apply(cf_def);
+ throw new AssertionError("Should have blown up when you used a
different name.");
+ }
+ catch (ConfigurationException expected)
+ {
+ cf_def.setName(oldStr);
+ }
+
+ oldStr = cf_def.getKeyspace();
+ try
+ {
+ cf_def.setKeyspace(oldStr + "_renamed");
+ updateCfm = cf.apply(cf_def);
+ throw new AssertionError("Should have blown up when you used a
different keyspace.");
+ }
+ catch (ConfigurationException expected)
+ {
+ cf_def.setKeyspace(oldStr);
+ }
+
+ try
+ {
+ cf_def.setColumn_type(ColumnFamilyType.Super.name());
+ updateCfm = cf.apply(cf_def);
+ throw new AssertionError("Should have blwon up when you used a
different cf type.");
+ }
+ catch (ConfigurationException expected)
+ {
+ cf_def.setColumn_type(ColumnFamilyType.Standard.name());
+ }
+
+ oldStr = cf_def.getComparator_type();
+ try
+ {
+ cf_def.setComparator_type(BytesType.class.getSimpleName());
+ updateCfm = cf.apply(cf_def);
+ throw new AssertionError("Should have blown up when you used a
different comparator.");
+ }
+ catch (ConfigurationException expected)
+ {
+ cf_def.setComparator_type(UTF8Type.class.getSimpleName());
+ }
+ }
}