package org.apache.cassandra.stress.settings;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.*;
import org.apache.cassandra.utils.ByteBufferUtil;
public class SettingsSchema implements Serializable
{
public static final String DEFAULT_COMPARATOR = "AsciiType";
public static final String DEFAULT_VALIDATOR = "BytesType";
private final String replicationStrategy;
private final Map<String, String> replicationStrategyOptions;
private final IndexType indexType;
private final boolean replicateOnWrite;
private final String compression;
private final String compactionStrategy;
public final String keyspace;
public final String columnFamily;
public SettingsSchema(Options options)
{
replicateOnWrite = !options.noReplicateOnWrite.setByUser();
replicationStrategy = options.replication.getStrategy();
replicationStrategyOptions = options.replication.getOptions();
if (options.index.setByUser())
indexType = IndexType.valueOf(options.index.value().toUpperCase());
else
indexType = null;
compression = options.compression.value();
compactionStrategy = options.compactionStrategy.value();
if (compactionStrategy != null)
{
try
{
CFMetaData.createCompactionStrategy(compactionStrategy);
} catch (ConfigurationException e)
{
throw new IllegalArgumentException("Invalid compaction strategy: " + compactionStrategy);
}
}
keyspace = options.keyspace.value();
columnFamily = options.columnFamily.value();
}
private void createKeyspacesCql3(StressSettings settings)
{
// settings.getJavaDriverClient().execute("create table Standard1")
}
public void createKeySpaces(StressSettings settings)
{
createKeySpacesThrift(settings);
}
/**
* Create Keyspace with Standard and Super/Counter column families
*/
public void createKeySpacesThrift(StressSettings settings)
{
KsDef ksdef = new KsDef();
// column family for standard columns
CfDef standardCfDef = new CfDef(keyspace, columnFamily);
Map<String, String> compressionOptions = new HashMap<String, String>();
if (compression != null)
compressionOptions.put("sstable_compression", compression);
String comparator = settings.columns.comparator;
standardCfDef.setComparator_type(comparator)
.setDefault_validation_class(DEFAULT_VALIDATOR)
.setCompression_options(compressionOptions);
if (!settings.columns.useTimeUUIDComparator)
{
for (int i = 0; i < settings.columns.maxColumnsPerKey; i++)
{
standardCfDef.addToColumn_metadata(new ColumnDef(ByteBufferUtil.bytes("C" + i), "BytesType"));
}
}
if (indexType != null)
{
ColumnDef standardColumn = new ColumnDef(ByteBufferUtil.bytes("C1"), "BytesType");
standardColumn.setIndex_type(indexType).setIndex_name("Idx1");
standardCfDef.setColumn_metadata(Arrays.asList(standardColumn));
}
// column family with super columns
CfDef superCfDef = new CfDef(keyspace, "Super1")
.setColumn_type("Super");
superCfDef.setComparator_type(DEFAULT_COMPARATOR)
.setSubcomparator_type(comparator)
.setDefault_validation_class(DEFAULT_VALIDATOR)
.setCompression_options(compressionOptions);
// column family for standard counters
CfDef counterCfDef = new CfDef(keyspace, "Counter1")
.setComparator_type(comparator)
.setDefault_validation_class("CounterColumnType")
.setReplicate_on_write(replicateOnWrite)
.setCompression_options(compressionOptions);
// column family with counter super columns
CfDef counterSuperCfDef = new CfDef(keyspace, "SuperCounter1")
.setComparator_type(comparator)
.setDefault_validation_class("CounterColumnType")
.setReplicate_on_write(replicateOnWrite)
.setColumn_type("Super")
.setCompression_options(compressionOptions);
ksdef.setName(keyspace);
ksdef.setStrategy_class(replicationStrategy);
if (!replicationStrategyOptions.isEmpty())
{
ksdef.setStrategy_options(replicationStrategyOptions);
}
if (compactionStrategy != null)
{
standardCfDef.setCompaction_strategy(compactionStrategy);
superCfDef.setCompaction_strategy(compactionStrategy);
counterCfDef.setCompaction_strategy(compactionStrategy);
counterSuperCfDef.setCompaction_strategy(compactionStrategy);
}
ksdef.setCf_defs(new ArrayList<CfDef>(Arrays.asList(standardCfDef, superCfDef, counterCfDef, counterSuperCfDef)));
Cassandra.Client client = settings.getRawThriftClient(false);
try
{
client.system_add_keyspace(ksdef);
/* CQL3 counter cf */
client.set_cql_version("3.0.0"); // just to create counter cf for cql3
client.set_keyspace(keyspace);
client.execute_cql3_query(createCounterCFStatementForCQL3(settings), Compression.NONE, ConsistencyLevel.ONE);
if (settings.mode.cqlVersion.isCql())
client.set_cql_version(settings.mode.cqlVersion.connectVersion);
/* end */
System.out.println(String.format("Created keyspaces. Sleeping %ss for propagation.", settings.node.nodes.size()));
Thread.sleep(settings.node.nodes.size() * 1000); // seconds
}
catch (InvalidRequestException e)
{
System.err.println("Unable to create stress keyspace: " + e.getWhy());
}
catch (Exception e)
{
System.err.println("!!!! " + e.getMessage());
}
}
private ByteBuffer createCounterCFStatementForCQL3(StressSettings options)
{
StringBuilder counter3 = new StringBuilder("CREATE TABLE \"Counter3\" (KEY blob PRIMARY KEY, ");
for (int i = 0; i < options.columns.maxColumnsPerKey; i++)
{
counter3.append("c").append(i).append(" counter");
if (i != options.columns.maxColumnsPerKey - 1)
counter3.append(", ");
}
counter3.append(");");
return ByteBufferUtil.bytes(counter3.toString());
}
// Option Declarations
private static final class Options extends GroupedOptions
{
final OptionReplication replication = new OptionReplication();
final OptionSimple index = new OptionSimple("index=", "KEYS|CUSTOM|COMPOSITES", null, "Type of index to create on needed column families (KEYS)", false);
final OptionSimple keyspace = new OptionSimple("keyspace=", ".*", "Keyspace1", "The keyspace name to use", false);
final OptionSimple columnFamily = new OptionSimple("columnfamily=", ".*", "Standard1", "The column family name to use", false);
final OptionSimple compactionStrategy = new OptionSimple("compaction=", ".*", null, "The compaction strategy to use", false);
final OptionSimple noReplicateOnWrite = new OptionSimple("no-replicate-on-write", "", null, "Set replicate_on_write to false for counters. Only counter add with CL=ONE will work", false);
final OptionSimple compression = new OptionSimple("compression=", ".*", null, "Specify the compression to use for sstable, default:no compression", false);
@Override
public List<? extends Option> options()
{
return Arrays.asList(replication, index, keyspace, columnFamily, compactionStrategy, noReplicateOnWrite, compression);
}
}
// CLI Utility Methods
public static SettingsSchema get(Map<String, String[]> clArgs)
{
String[] params = clArgs.remove("-schema");
if (params == null)
return new SettingsSchema(new Options());
GroupedOptions options = GroupedOptions.select(params, new Options());
if (options == null)
{
printHelp();
System.out.println("Invalid -schema options provided, see output for valid options");
System.exit(1);
}
return new SettingsSchema((Options) options);
}
public static void printHelp()
{
GroupedOptions.printOptions(System.out, "-schema", new Options());
}
public static Runnable helpPrinter()
{
return new Runnable()
{
@Override
public void run()
{
printHelp();
}
};
}
}