mirror of https://github.com/apache/cassandra
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:
parent
c213967e43
commit
7b9f69ad18
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue