push access structures into KSM. patch by stuhood, reviewed by gdusbabek. CASSANDRA-1237

git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@980220 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gary Dusbabek 2010-07-28 21:01:49 +00:00
parent c213967e43
commit 7b9f69ad18
7 changed files with 78 additions and 21 deletions

View File

@ -521,6 +521,16 @@ public class CassandraServer implements Cassandra {
return new org.apache.cassandra.db.TimestampClock(clock.timestamp);
}
private static Map<String,AccessLevel> unavronateAccessMap(Map<Utf8,AccessLevel> map)
{
Map<String,AccessLevel> out = new HashMap<String,AccessLevel>();
if (map == null)
return out;
for (Map.Entry<Utf8, AccessLevel> entry : map.entrySet())
out.put(entry.getKey().toString(), entry.getValue());
return out;
}
// FIXME: This is copypasta from o.a.c.db.RowMutation, (RowMutation.getRowMutation uses Thrift types directly).
private static RowMutation getRowMutationFromMutations(String keyspace, byte[] key, Map<Utf8, GenericArray<Mutation>> cfMap)
{
@ -666,6 +676,8 @@ public class CassandraServer implements Cassandra {
ksDef.name.toString(),
(Class<? extends AbstractReplicationStrategy>)Class.forName(ksDef.strategy_class.toString()),
(int)ksDef.replication_factor,
unavronateAccessMap(ksDef.users_access),
unavronateAccessMap(ksDef.groups_access),
cfDefs.toArray(new CFMetaData[cfDefs.size()]));
AddKeyspace add = new AddKeyspace(ksmeta);
add.apply();

View File

@ -343,11 +343,16 @@ public class DatabaseDescriptor
CommitLog.setSegmentSize(conf.commitlog_rotation_threshold_in_mb * 1024 * 1024);
// Hardcoded system tables
KSMetaData systemMeta = new KSMetaData(Table.SYSTEM_TABLE, LocalStrategy.class, 1, new CFMetaData[]{CFMetaData.StatusCf,
CFMetaData.HintsCf,
CFMetaData.MigrationsCf,
CFMetaData.SchemaCf,
CFMetaData.StatisticsCf
KSMetaData systemMeta = new KSMetaData(Table.SYSTEM_TABLE,
LocalStrategy.class,
1,
null,
null,
new CFMetaData[]{CFMetaData.StatusCf,
CFMetaData.HintsCf,
CFMetaData.MigrationsCf,
CFMetaData.SchemaCf,
CFMetaData.StatisticsCf
});
CFMetaData.map(CFMetaData.StatusCf);
CFMetaData.map(CFMetaData.HintsCf);
@ -617,7 +622,7 @@ public class DatabaseDescriptor
cf.gc_grace_seconds,
metadata);
}
defs.add(new KSMetaData(keyspace.name, strategyClass, keyspace.replication_factor, cfDefs));
defs.add(new KSMetaData(keyspace.name, strategyClass, keyspace.replication_factor, null, null, cfDefs));
}

View File

@ -32,14 +32,18 @@ import java.util.Map;
import org.apache.avro.util.Utf8;
import org.apache.commons.lang.ObjectUtils;
import org.apache.cassandra.avro.AccessLevel;
public final class KSMetaData
{
public final String name;
public final Class<? extends AbstractReplicationStrategy> strategyClass;
public final int replicationFactor;
private final Map<String, CFMetaData> cfMetaData;
public final Map<String, CFMetaData> cfMetaData;
public final Map<String, AccessLevel> usersAccess;
public final Map<String, AccessLevel> groupsAccess;
public KSMetaData(String name, Class<? extends AbstractReplicationStrategy> strategyClass, int replicationFactor, CFMetaData... cfDefs)
public KSMetaData(String name, Class<? extends AbstractReplicationStrategy> strategyClass, int replicationFactor, Map<String,AccessLevel> usersAccess, Map<String,AccessLevel> groupsAccess, CFMetaData... cfDefs)
{
this.name = name;
this.strategyClass = strategyClass == null ? RackUnawareStrategy.class : strategyClass;
@ -48,6 +52,10 @@ public final class KSMetaData
for (CFMetaData cfm : cfDefs)
cfmap.put(cfm.cfName, cfm);
this.cfMetaData = Collections.unmodifiableMap(cfmap);
this.usersAccess = usersAccess == null ?
Collections.<String, AccessLevel>emptyMap() : Collections.unmodifiableMap(usersAccess);
this.groupsAccess = groupsAccess == null ?
Collections.<String, AccessLevel>emptyMap() : Collections.unmodifiableMap(groupsAccess);
}
/**
@ -57,7 +65,7 @@ public final class KSMetaData
{
List<CFMetaData> newCfs = new ArrayList<CFMetaData>(cfMetaData().values());
newCfs.add(cfm);
return new KSMetaData(name, strategyClass, replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
return new KSMetaData(name, strategyClass, replicationFactor, usersAccess, groupsAccess, newCfs.toArray(new CFMetaData[newCfs.size()]));
}
/**
@ -69,7 +77,7 @@ public final class KSMetaData
List<CFMetaData> newCfs = new ArrayList<CFMetaData>(cfMetaData().values());
newCfs.remove(cfm);
assert newCfs.size() == cfMetaData().size() - 1;
return new KSMetaData(name, strategyClass, replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
return new KSMetaData(name, strategyClass, replicationFactor, usersAccess, groupsAccess, newCfs.toArray(new CFMetaData[newCfs.size()]));
}
/**
@ -81,7 +89,7 @@ public final class KSMetaData
List<CFMetaData> newCfs = new ArrayList<CFMetaData>(cfMetaData().size());
for (CFMetaData oldCf : cfMetaData().values())
newCfs.add(CFMetaData.renameTable(oldCf, ksName));
return new KSMetaData(ksName, strategyClass, replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
return new KSMetaData(ksName, strategyClass, replicationFactor, usersAccess, groupsAccess, newCfs.toArray(new CFMetaData[newCfs.size()]));
}
public boolean equals(Object obj)
@ -102,13 +110,15 @@ public final class KSMetaData
{
return cfMetaData;
}
public org.apache.cassandra.avro.KsDef deflate()
{
org.apache.cassandra.avro.KsDef ks = new org.apache.cassandra.avro.KsDef();
ks.name = new Utf8(name);
ks.strategy_class = new Utf8(strategyClass.getName());
ks.replication_factor = replicationFactor;
ks.users_access = SerDeUtils.toAvroMap(usersAccess);
ks.groups_access = SerDeUtils.toAvroMap(groupsAccess);
ks.cf_defs = SerDeUtils.createArray(cfMetaData.size(), org.apache.cassandra.avro.CfDef.SCHEMA$);
for (CFMetaData cfm : cfMetaData.values())
ks.cf_defs.add(cfm.deflate());
@ -126,12 +136,14 @@ public final class KSMetaData
{
throw new ConfigurationException("Could not create ReplicationStrategy of type " + ks.strategy_class, ex);
}
Map<String,AccessLevel> usersAccess = SerDeUtils.fromAvroMap(ks.users_access);
Map<String,AccessLevel> groupsAccess = SerDeUtils.fromAvroMap(ks.groups_access);
int cfsz = (int)ks.cf_defs.size();
CFMetaData[] cfMetaData = new CFMetaData[cfsz];
Iterator<org.apache.cassandra.avro.CfDef> cfiter = ks.cf_defs.iterator();
for (int i = 0; i < cfsz; i++)
cfMetaData[i] = CFMetaData.inflate(cfiter.next());
return new KSMetaData(ks.name.toString(), repStratClass, ks.replication_factor, cfMetaData);
return new KSMetaData(ks.name.toString(), repStratClass, ks.replication_factor, usersAccess, groupsAccess, cfMetaData);
}
}

View File

@ -22,6 +22,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.HashMap;
import org.apache.avro.Schema;
import org.apache.avro.io.BinaryDecoder;
@ -45,6 +47,22 @@ public final class SerDeUtils
// unbuffered decoders
private final static DecoderFactory DIRECT_DECODERS = new DecoderFactory().configureDirectDecoder(true);
public static <T> Map<Utf8,T> toAvroMap(Map<String,T> map)
{
Map<Utf8,T> out = new HashMap<Utf8,T>();
for (Map.Entry<String,T> entry : map.entrySet())
out.put(new Utf8(entry.getKey()), entry.getValue());
return out;
}
public static <T> Map<String,T> fromAvroMap(Map<Utf8,T> map)
{
Map<String,T> out = new HashMap<String,T>();
for (Map.Entry<Utf8,T> entry : map.entrySet())
out.put(entry.getKey().toString(), entry.getValue());
return out;
}
/**
* Deserializes a single object based on the given Schema.
* @param schema writer's schema

View File

@ -225,6 +225,16 @@ public class CassandraServer implements Cassandra.Iface
return thrift_clock;
}
private static Map<String,org.apache.cassandra.avro.AccessLevel> unthriftifyAccessMap(Map<String,AccessLevel> map)
{
Map<String,org.apache.cassandra.avro.AccessLevel> out = new HashMap<String,org.apache.cassandra.avro.AccessLevel>();
if (map == null)
return out;
for (Map.Entry<String,AccessLevel> entry : map.entrySet())
out.put(entry.getKey(), Enum.valueOf(org.apache.cassandra.avro.AccessLevel.class, entry.getValue().name()));
return out;
}
private Map<byte[], List<ColumnOrSuperColumn>> getSlice(List<ReadCommand> commands, ConsistencyLevel consistency_level)
throws InvalidRequestException, UnavailableException, TimedOutException
{
@ -881,7 +891,9 @@ public class CassandraServer implements Cassandra.Iface
KSMetaData ksm = new KSMetaData(
ks_def.name,
(Class<? extends AbstractReplicationStrategy>)Class.forName(ks_def.strategy_class),
ks_def.replication_factor,
ks_def.replication_factor,
unthriftifyAccessMap(ks_def.users_access),
unthriftifyAccessMap(ks_def.groups_access),
cfDefs.toArray(new CFMetaData[cfDefs.size()]));
applyMigrationOnStage(new AddKeyspace(ksm));
return DatabaseDescriptor.getDefsVersion().toString();

View File

@ -37,9 +37,7 @@ public class DatabaseDescriptorTest
{
protected <D extends SpecificRecord> D serDe(D record) throws IOException
{
D actual = SerDeUtils.<D>deserialize(record.getSchema(), SerDeUtils.serialize(record));
assert actual.equals(record) : actual + " != " + record;
return actual;
return SerDeUtils.<D>deserialize(record.getSchema(), SerDeUtils.serialize(record));
}
@Test
@ -83,9 +81,9 @@ public class DatabaseDescriptorTest
assert DatabaseDescriptor.getNonSystemTables().size() == 0;
// add a few.
AddKeyspace ks0 = new AddKeyspace(new KSMetaData("ks0", RackUnawareStrategy.class, 3));
AddKeyspace ks0 = new AddKeyspace(new KSMetaData("ks0", RackUnawareStrategy.class, 3, null, null));
ks0.apply();
AddKeyspace ks1 = new AddKeyspace(new KSMetaData("ks1", RackUnawareStrategy.class, 3));
AddKeyspace ks1 = new AddKeyspace(new KSMetaData("ks1", RackUnawareStrategy.class, 3, null, null));
ks1.apply();
assert DatabaseDescriptor.getTableDefinition("ks0") != null;

View File

@ -262,7 +262,7 @@ public class DefsTest extends CleanupHelper
{
DecoratedKey dk = Util.dk("key0");
CFMetaData newCf = new CFMetaData("NewKeyspace1", "AddedStandard1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "A new cf for a new ks", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
KSMetaData newKs = new KSMetaData(newCf.tableName, RackUnawareStrategy.class, 5, newCf);
KSMetaData newKs = new KSMetaData(newCf.tableName, RackUnawareStrategy.class, 5, null, null, newCf);
new AddKeyspace(newKs).apply();
@ -414,7 +414,7 @@ public class DefsTest extends CleanupHelper
{
assert DatabaseDescriptor.getTableDefinition("EmptyKeyspace") == null;
KSMetaData newKs = new KSMetaData("EmptyKeyspace", RackUnawareStrategy.class, 5, new CFMetaData[]{});
KSMetaData newKs = new KSMetaData("EmptyKeyspace", RackUnawareStrategy.class, 5, null, null);
new AddKeyspace(newKs).apply();
assert DatabaseDescriptor.getTableDefinition("EmptyKeyspace") != null;