| /* |
| * 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. |
| */ |
| package org.apache.cassandra; |
| |
| import java.io.IOException; |
| import java.util.*; |
| |
| import org.apache.cassandra.auth.AuthKeyspace; |
| import org.apache.cassandra.auth.AuthSchemaChangeListener; |
| import org.apache.cassandra.auth.IAuthenticator; |
| import org.apache.cassandra.auth.IAuthorizer; |
| import org.apache.cassandra.auth.INetworkAuthorizer; |
| import org.apache.cassandra.auth.IRoleManager; |
| import org.apache.cassandra.config.*; |
| import org.apache.cassandra.cql3.ColumnIdentifier; |
| import org.apache.cassandra.cql3.statements.schema.CreateTableStatement; |
| import org.apache.cassandra.cql3.statements.schema.IndexTarget; |
| import org.apache.cassandra.db.RowUpdateBuilder; |
| import org.apache.cassandra.db.marshal.*; |
| import org.apache.cassandra.dht.Murmur3Partitioner; |
| import org.apache.cassandra.exceptions.ConfigurationException; |
| import org.apache.cassandra.gms.Gossiper; |
| import org.apache.cassandra.index.StubIndex; |
| import org.apache.cassandra.index.sasi.SASIIndex; |
| import org.apache.cassandra.index.sasi.disk.OnDiskIndexBuilder; |
| import org.apache.cassandra.schema.*; |
| import org.apache.cassandra.schema.MigrationManager; |
| import org.apache.cassandra.utils.ByteBufferUtil; |
| import org.apache.cassandra.utils.FBUtilities; |
| |
| import org.junit.After; |
| import org.junit.BeforeClass; |
| |
| public class SchemaLoader |
| { |
| @BeforeClass |
| public static void loadSchema() throws ConfigurationException |
| { |
| prepareServer(); |
| |
| // Migrations aren't happy if gossiper is not started. Even if we don't use migrations though, |
| // some tests now expect us to start gossip for them. |
| startGossiper(); |
| } |
| |
| @After |
| public void leakDetect() throws InterruptedException |
| { |
| System.gc(); |
| System.gc(); |
| System.gc(); |
| Thread.sleep(10); |
| } |
| |
| public static void prepareServer() |
| { |
| ServerTestUtils.daemonInitialization(); |
| ServerTestUtils.prepareServer(); |
| } |
| |
| public static void startGossiper() |
| { |
| // skip shadow round and endpoint collision check in tests |
| System.setProperty("cassandra.allow_unsafe_join", "true"); |
| if (!Gossiper.instance.isEnabled()) |
| Gossiper.instance.start((int) (System.currentTimeMillis() / 1000)); |
| } |
| |
| public static void schemaDefinition(String testName) throws ConfigurationException |
| { |
| List<KeyspaceMetadata> schema = new ArrayList<KeyspaceMetadata>(); |
| |
| // A whole bucket of shorthand |
| String ks1 = testName + "Keyspace1"; |
| String ks2 = testName + "Keyspace2"; |
| String ks3 = testName + "Keyspace3"; |
| String ks4 = testName + "Keyspace4"; |
| String ks5 = testName + "Keyspace5"; |
| String ks6 = testName + "Keyspace6"; |
| String ks7 = testName + "Keyspace7"; |
| String ks_kcs = testName + "KeyCacheSpace"; |
| String ks_rcs = testName + "RowCacheSpace"; |
| String ks_ccs = testName + "CounterCacheSpace"; |
| String ks_nocommit = testName + "NoCommitlogSpace"; |
| String ks_prsi = testName + "PerRowSecondaryIndex"; |
| String ks_cql = testName + "cql_keyspace"; |
| String ks_cql_replicated = testName + "cql_keyspace_replicated"; |
| String ks_with_transient = testName + "ks_with_transient"; |
| |
| AbstractType bytes = BytesType.instance; |
| |
| AbstractType<?> composite = CompositeType.getInstance(Arrays.asList(new AbstractType<?>[]{BytesType.instance, TimeUUIDType.instance, IntegerType.instance})); |
| AbstractType<?> compositeMaxMin = CompositeType.getInstance(Arrays.asList(new AbstractType<?>[]{BytesType.instance, IntegerType.instance})); |
| Map<Byte, AbstractType<?>> aliases = new HashMap<Byte, AbstractType<?>>(); |
| aliases.put((byte)'b', BytesType.instance); |
| aliases.put((byte)'t', TimeUUIDType.instance); |
| aliases.put((byte)'B', ReversedType.getInstance(BytesType.instance)); |
| aliases.put((byte)'T', ReversedType.getInstance(TimeUUIDType.instance)); |
| AbstractType<?> dynamicComposite = DynamicCompositeType.getInstance(aliases); |
| |
| // Make it easy to test compaction |
| Map<String, String> compactionOptions = new HashMap<String, String>(); |
| compactionOptions.put("tombstone_compaction_interval", "1"); |
| Map<String, String> leveledOptions = new HashMap<String, String>(); |
| leveledOptions.put("sstable_size_in_mb", "1"); |
| leveledOptions.put("fanout_size", "5"); |
| |
| // Keyspace 1 |
| schema.add(KeyspaceMetadata.create(ks1, |
| KeyspaceParams.simple(1), |
| Tables.of( |
| // Column Families |
| standardCFMD(ks1, "Standard1").compaction(CompactionParams.stcs(compactionOptions)).build(), |
| standardCFMD(ks1, "Standard2").build(), |
| standardCFMD(ks1, "Standard3").build(), |
| standardCFMD(ks1, "Standard4").build(), |
| standardCFMD(ks1, "StandardGCGS0").gcGraceSeconds(0).build(), |
| standardCFMD(ks1, "StandardLong1").build(), |
| standardCFMD(ks1, "StandardLong2").build(), |
| keysIndexCFMD(ks1, "Indexed1", true).build(), |
| keysIndexCFMD(ks1, "Indexed2", false).build(), |
| jdbcCFMD(ks1, "JdbcUtf8", UTF8Type.instance).addColumn(utf8Column(ks1, "JdbcUtf8")).build(), |
| jdbcCFMD(ks1, "JdbcLong", LongType.instance).build(), |
| jdbcCFMD(ks1, "JdbcBytes", bytes).build(), |
| jdbcCFMD(ks1, "JdbcAscii", AsciiType.instance).build(), |
| standardCFMD(ks1, "StandardLeveled").compaction(CompactionParams.lcs(leveledOptions)).build(), |
| standardCFMD(ks1, "legacyleveled").compaction(CompactionParams.lcs(leveledOptions)).build(), |
| standardCFMD(ks1, "StandardLowIndexInterval").minIndexInterval(8) |
| .maxIndexInterval(256) |
| .caching(CachingParams.CACHE_NOTHING).build() |
| ))); |
| |
| // Keyspace 2 |
| schema.add(KeyspaceMetadata.create(ks2, |
| KeyspaceParams.simple(1), |
| Tables.of( |
| // Column Families |
| standardCFMD(ks2, "Standard1").build(), |
| standardCFMD(ks2, "Standard3").build(), |
| keysIndexCFMD(ks2, "Indexed1", true).build(), |
| compositeIndexCFMD(ks2, "Indexed2", true).build(), |
| compositeIndexCFMD(ks2, "Indexed3", true).gcGraceSeconds(0).build()))); |
| |
| // Keyspace 3 |
| schema.add(KeyspaceMetadata.create(ks3, |
| KeyspaceParams.simple(5), |
| Tables.of( |
| standardCFMD(ks3, "Standard1").build(), |
| keysIndexCFMD(ks3, "Indexed1", true).build()))); |
| |
| // Keyspace 4 |
| schema.add(KeyspaceMetadata.create(ks4, |
| KeyspaceParams.simple(3), |
| Tables.of( |
| standardCFMD(ks4, "Standard1").build(), |
| standardCFMD(ks4, "Standard3").build()))); |
| |
| // Keyspace 5 |
| schema.add(KeyspaceMetadata.create(ks5, |
| KeyspaceParams.simple(2), |
| Tables.of(standardCFMD(ks5, "Standard1").build()))); |
| |
| // Keyspace 6 |
| schema.add(KeyspaceMetadata.create(ks6, |
| KeyspaceParams.simple(1), |
| Tables.of(keysIndexCFMD(ks6, "Indexed1", true).build()))); |
| |
| // Keyspace 7 |
| schema.add(KeyspaceMetadata.create(ks7, |
| KeyspaceParams.simple(1), |
| Tables.of(customIndexCFMD(ks7, "Indexed1").build()))); |
| |
| // KeyCacheSpace |
| schema.add(KeyspaceMetadata.create(ks_kcs, |
| KeyspaceParams.simple(1), |
| Tables.of( |
| standardCFMD(ks_kcs, "Standard1").build(), |
| standardCFMD(ks_kcs, "Standard2").build(), |
| standardCFMD(ks_kcs, "Standard3").build()))); |
| |
| // RowCacheSpace |
| schema.add(KeyspaceMetadata.create(ks_rcs, |
| KeyspaceParams.simple(1), |
| Tables.of( |
| standardCFMD(ks_rcs, "CFWithoutCache").caching(CachingParams.CACHE_NOTHING).build(), |
| standardCFMD(ks_rcs, "CachedCF").caching(CachingParams.CACHE_EVERYTHING).build(), |
| standardCFMD(ks_rcs, "CachedNoClustering", 1, IntegerType.instance, IntegerType.instance, null).caching(CachingParams.CACHE_EVERYTHING).build(), |
| standardCFMD(ks_rcs, "CachedIntCF").caching(new CachingParams(true, 100)).build()))); |
| |
| schema.add(KeyspaceMetadata.create(ks_nocommit, KeyspaceParams.simpleTransient(1), Tables.of( |
| standardCFMD(ks_nocommit, "Standard1").build()))); |
| |
| String simpleTable = "CREATE TABLE table1 (" |
| + "k int PRIMARY KEY," |
| + "v1 text," |
| + "v2 int" |
| + ")"; |
| // CQLKeyspace |
| schema.add(KeyspaceMetadata.create(ks_cql, KeyspaceParams.simple(1), Tables.of( |
| |
| // Column Families |
| CreateTableStatement.parse(simpleTable, ks_cql).build(), |
| |
| CreateTableStatement.parse("CREATE TABLE table2 (" |
| + "k text," |
| + "c text," |
| + "v text," |
| + "PRIMARY KEY (k, c))", ks_cql) |
| .build() |
| ))); |
| |
| schema.add(KeyspaceMetadata.create(ks_cql_replicated, KeyspaceParams.simple(3), |
| Tables.of(CreateTableStatement.parse(simpleTable, ks_cql_replicated).build()))); |
| |
| schema.add(KeyspaceMetadata.create(ks_with_transient, KeyspaceParams.simple("3/1"), |
| Tables.of(CreateTableStatement.parse(simpleTable, ks_with_transient).build()))); |
| |
| if (DatabaseDescriptor.getPartitioner() instanceof Murmur3Partitioner) |
| { |
| schema.add(KeyspaceMetadata.create("sasi", |
| KeyspaceParams.simpleTransient(1), |
| Tables.of(sasiCFMD("sasi", "test_cf").build(), |
| clusteringSASICFMD("sasi", "clustering_test_cf").build()))); |
| } |
| |
| // if you're messing with low-level sstable stuff, it can be useful to inject the schema directly |
| // Schema.instance.load(schemaDefinition()); |
| for (KeyspaceMetadata ksm : schema) |
| MigrationManager.announceNewKeyspace(ksm, false); |
| |
| if (Boolean.parseBoolean(System.getProperty("cassandra.test.compression", "false"))) |
| useCompression(schema, compressionParams(CompressionParams.DEFAULT_CHUNK_LENGTH)); |
| } |
| |
| public static void createKeyspace(String name, KeyspaceParams params) |
| { |
| MigrationManager.announceNewKeyspace(KeyspaceMetadata.create(name, params, Tables.of()), true); |
| } |
| |
| public static void createKeyspace(String name, KeyspaceParams params, TableMetadata.Builder... builders) |
| { |
| Tables.Builder tables = Tables.builder(); |
| for (TableMetadata.Builder builder : builders) |
| tables.add(builder.build()); |
| |
| MigrationManager.announceNewKeyspace(KeyspaceMetadata.create(name, params, tables.build()), true); |
| } |
| |
| public static void createKeyspace(String name, KeyspaceParams params, TableMetadata... tables) |
| { |
| MigrationManager.announceNewKeyspace(KeyspaceMetadata.create(name, params, Tables.of(tables)), true); |
| } |
| |
| public static void createKeyspace(String name, KeyspaceParams params, Tables tables, Types types) |
| { |
| MigrationManager.announceNewKeyspace(KeyspaceMetadata.create(name, params, tables, Views.none(), types, Functions.none()), true); |
| } |
| |
| public static void setupAuth(IRoleManager roleManager, IAuthenticator authenticator, IAuthorizer authorizer, INetworkAuthorizer networkAuthorizer) |
| { |
| DatabaseDescriptor.setRoleManager(roleManager); |
| DatabaseDescriptor.setAuthenticator(authenticator); |
| DatabaseDescriptor.setAuthorizer(authorizer); |
| DatabaseDescriptor.setNetworkAuthorizer(networkAuthorizer); |
| MigrationManager.announceNewKeyspace(AuthKeyspace.metadata(), true); |
| DatabaseDescriptor.getRoleManager().setup(); |
| DatabaseDescriptor.getAuthenticator().setup(); |
| DatabaseDescriptor.getAuthorizer().setup(); |
| DatabaseDescriptor.getNetworkAuthorizer().setup(); |
| Schema.instance.registerListener(new AuthSchemaChangeListener()); |
| } |
| |
| public static ColumnMetadata integerColumn(String ksName, String cfName) |
| { |
| return new ColumnMetadata(ksName, |
| cfName, |
| ColumnIdentifier.getInterned(IntegerType.instance.fromString("42"), IntegerType.instance), |
| UTF8Type.instance, |
| ColumnMetadata.NO_POSITION, |
| ColumnMetadata.Kind.REGULAR); |
| } |
| |
| public static ColumnMetadata utf8Column(String ksName, String cfName) |
| { |
| return new ColumnMetadata(ksName, |
| cfName, |
| ColumnIdentifier.getInterned("fortytwo", true), |
| UTF8Type.instance, |
| ColumnMetadata.NO_POSITION, |
| ColumnMetadata.Kind.REGULAR); |
| } |
| |
| public static TableMetadata perRowIndexedCFMD(String ksName, String cfName) |
| { |
| ColumnMetadata indexedColumn = ColumnMetadata.regularColumn(ksName, cfName, "indexed", AsciiType.instance); |
| |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addColumn(indexedColumn); |
| |
| final Map<String, String> indexOptions = Collections.singletonMap(IndexTarget.CUSTOM_INDEX_OPTION_NAME, StubIndex.class.getName()); |
| builder.indexes(Indexes.of(IndexMetadata.fromIndexTargets( |
| Collections.singletonList(new IndexTarget(indexedColumn.name, |
| IndexTarget.Type.VALUES)), |
| "indexe1", |
| IndexMetadata.Kind.CUSTOM, |
| indexOptions))); |
| |
| return builder.build(); |
| } |
| |
| private static void useCompression(List<KeyspaceMetadata> schema, CompressionParams compressionParams) |
| { |
| for (KeyspaceMetadata ksm : schema) |
| for (TableMetadata cfm : ksm.tablesAndViews()) |
| MigrationManager.announceTableUpdate(cfm.unbuild().compression(compressionParams.copy()).build(), true); |
| } |
| |
| public static TableMetadata.Builder counterCFMD(String ksName, String cfName) |
| { |
| return TableMetadata.builder(ksName, cfName) |
| .isCounter(true) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("name", AsciiType.instance) |
| .addRegularColumn("val", CounterColumnType.instance) |
| .addRegularColumn("val2", CounterColumnType.instance) |
| .compression(getCompressionParameters()); |
| } |
| |
| public static TableMetadata.Builder standardCFMD(String ksName, String cfName) |
| { |
| return standardCFMD(ksName, cfName, 1, AsciiType.instance); |
| } |
| |
| public static TableMetadata.Builder standardCFMD(String ksName, String cfName, int columnCount, AbstractType<?> keyType) |
| { |
| return standardCFMD(ksName, cfName, columnCount, keyType, AsciiType.instance); |
| } |
| |
| public static TableMetadata.Builder standardCFMD(String ksName, String cfName, int columnCount, AbstractType<?> keyType, AbstractType<?> valType) |
| { |
| return standardCFMD(ksName, cfName, columnCount, keyType, valType, AsciiType.instance); |
| } |
| |
| public static TableMetadata.Builder standardCFMD(String ksName, String cfName, int columnCount, AbstractType<?> keyType, AbstractType<?> valType, AbstractType<?> clusteringType) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", keyType) |
| .addRegularColumn("val", valType) |
| .compression(getCompressionParameters()); |
| |
| if (clusteringType != null) |
| builder.addClusteringColumn("name", clusteringType); |
| |
| for (int i = 0; i < columnCount; i++) |
| builder.addRegularColumn("val" + i, AsciiType.instance); |
| |
| return builder; |
| } |
| |
| public static TableMetadata.Builder staticCFMD(String ksName, String cfName) |
| { |
| return TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("cols", AsciiType.instance) |
| .addStaticColumn("val", AsciiType.instance) |
| .addRegularColumn("val2", AsciiType.instance); |
| } |
| |
| public static TableMetadata.Builder compositeIndexCFMD(String ksName, String cfName, boolean withRegularIndex) throws ConfigurationException |
| { |
| return compositeIndexCFMD(ksName, cfName, withRegularIndex, false); |
| } |
| |
| public static TableMetadata.Builder compositeIndexCFMD(String ksName, String cfName, boolean withRegularIndex, boolean withStaticIndex) throws ConfigurationException |
| { |
| // the withIndex flag exists to allow tests index creation |
| // on existing columns |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("c1", AsciiType.instance) |
| .addRegularColumn("birthdate", LongType.instance) |
| .addRegularColumn("notbirthdate", LongType.instance) |
| .addStaticColumn("static", LongType.instance) |
| .compression(getCompressionParameters()); |
| |
| Indexes.Builder indexes = Indexes.builder(); |
| |
| if (withRegularIndex) |
| { |
| indexes.add(IndexMetadata.fromIndexTargets( |
| Collections.singletonList( |
| new IndexTarget(new ColumnIdentifier("birthdate", true), |
| IndexTarget.Type.VALUES)), |
| cfName + "_birthdate_key_index", |
| IndexMetadata.Kind.COMPOSITES, |
| Collections.EMPTY_MAP)); |
| } |
| |
| if (withStaticIndex) |
| { |
| indexes.add(IndexMetadata.fromIndexTargets( |
| Collections.singletonList( |
| new IndexTarget(new ColumnIdentifier("static", true), |
| IndexTarget.Type.VALUES)), |
| cfName + "_static_index", |
| IndexMetadata.Kind.COMPOSITES, |
| Collections.EMPTY_MAP)); |
| } |
| |
| return builder.indexes(indexes.build()); |
| } |
| |
| public static TableMetadata.Builder compositeMultipleIndexCFMD(String ksName, String cfName) throws ConfigurationException |
| { |
| TableMetadata.Builder builder = TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("c1", AsciiType.instance) |
| .addRegularColumn("birthdate", LongType.instance) |
| .addRegularColumn("notbirthdate", LongType.instance) |
| .compression(getCompressionParameters()); |
| |
| |
| Indexes.Builder indexes = Indexes.builder(); |
| |
| indexes.add(IndexMetadata.fromIndexTargets(Collections.singletonList( |
| new IndexTarget(new ColumnIdentifier("birthdate", true), |
| IndexTarget.Type.VALUES)), |
| "birthdate_key_index", |
| IndexMetadata.Kind.COMPOSITES, |
| Collections.EMPTY_MAP)); |
| indexes.add(IndexMetadata.fromIndexTargets(Collections.singletonList( |
| new IndexTarget(new ColumnIdentifier("notbirthdate", true), |
| IndexTarget.Type.VALUES)), |
| "notbirthdate_key_index", |
| IndexMetadata.Kind.COMPOSITES, |
| Collections.EMPTY_MAP)); |
| |
| |
| return builder.indexes(indexes.build()); |
| } |
| |
| public static TableMetadata.Builder keysIndexCFMD(String ksName, String cfName, boolean withIndex) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("c1", AsciiType.instance) |
| .addStaticColumn("birthdate", LongType.instance) |
| .addStaticColumn("notbirthdate", LongType.instance) |
| .addRegularColumn("value", LongType.instance) |
| .compression(getCompressionParameters()); |
| |
| if (withIndex) |
| { |
| IndexMetadata index = |
| IndexMetadata.fromIndexTargets( |
| Collections.singletonList(new IndexTarget(new ColumnIdentifier("birthdate", true), |
| IndexTarget.Type.VALUES)), |
| cfName + "_birthdate_composite_index", |
| IndexMetadata.Kind.KEYS, |
| Collections.EMPTY_MAP); |
| builder.indexes(Indexes.builder().add(index).build()); |
| } |
| |
| return builder; |
| } |
| |
| public static TableMetadata.Builder customIndexCFMD(String ksName, String cfName) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", AsciiType.instance) |
| .addClusteringColumn("c1", AsciiType.instance) |
| .addRegularColumn("value", LongType.instance) |
| .compression(getCompressionParameters()); |
| |
| IndexMetadata index = |
| IndexMetadata.fromIndexTargets( |
| Collections.singletonList(new IndexTarget(new ColumnIdentifier("value", true), IndexTarget.Type.VALUES)), |
| cfName + "_value_index", |
| IndexMetadata.Kind.CUSTOM, |
| Collections.singletonMap(IndexTarget.CUSTOM_INDEX_OPTION_NAME, StubIndex.class.getName())); |
| |
| builder.indexes(Indexes.of(index)); |
| |
| return builder; |
| } |
| |
| public static TableMetadata.Builder jdbcCFMD(String ksName, String cfName, AbstractType comp) |
| { |
| return TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("key", BytesType.instance) |
| .compression(getCompressionParameters()); |
| } |
| |
| public static TableMetadata.Builder sasiCFMD(String ksName, String cfName) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("id", UTF8Type.instance) |
| .addRegularColumn("first_name", UTF8Type.instance) |
| .addRegularColumn("last_name", UTF8Type.instance) |
| .addRegularColumn("age", Int32Type.instance) |
| .addRegularColumn("height", Int32Type.instance) |
| .addRegularColumn("timestamp", LongType.instance) |
| .addRegularColumn("address", UTF8Type.instance) |
| .addRegularColumn("score", DoubleType.instance) |
| .addRegularColumn("comment", UTF8Type.instance) |
| .addRegularColumn("comment_suffix_split", UTF8Type.instance) |
| .addRegularColumn("/output/full-name/", UTF8Type.instance) |
| .addRegularColumn("/data/output/id", UTF8Type.instance) |
| .addRegularColumn("first_name_prefix", UTF8Type.instance); |
| |
| Indexes.Builder indexes = Indexes.builder(); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_first_name", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "first_name"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_last_name", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "last_name"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_age", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "age"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_timestamp", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "timestamp"); |
| put("mode", OnDiskIndexBuilder.Mode.SPARSE.toString()); |
| |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_address", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put("analyzer_class", "org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer"); |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "address"); |
| put("mode", OnDiskIndexBuilder.Mode.PREFIX.toString()); |
| put("case_sensitive", "false"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_score", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "score"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_comment", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "comment"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| put("analyzed", "true"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_comment_suffix_split", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "comment_suffix_split"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| put("analyzed", "false"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_output_full_name", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "/output/full-name/"); |
| put("analyzed", "true"); |
| put("analyzer_class", "org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer"); |
| put("case_sensitive", "false"); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_data_output_id", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "/data/output/id"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| }})) |
| .add(IndexMetadata.fromSchemaMetadata(cfName + "_first_name_prefix", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "first_name_prefix"); |
| put("analyzed", "true"); |
| put("tokenization_normalize_lowercase", "true"); |
| }})); |
| |
| return builder.indexes(indexes.build()); |
| } |
| |
| public static TableMetadata.Builder clusteringSASICFMD(String ksName, String cfName) |
| { |
| return clusteringSASICFMD(ksName, cfName, "location", "age", "height", "score"); |
| } |
| |
| public static TableMetadata.Builder clusteringSASICFMD(String ksName, String cfName, String...indexedColumns) |
| { |
| Indexes.Builder indexes = Indexes.builder(); |
| for (String indexedColumn : indexedColumns) |
| { |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_" + indexedColumn, IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, indexedColumn); |
| put("mode", OnDiskIndexBuilder.Mode.PREFIX.toString()); |
| }})); |
| } |
| |
| return TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("name", UTF8Type.instance) |
| .addClusteringColumn("location", UTF8Type.instance) |
| .addClusteringColumn("age", Int32Type.instance) |
| .addRegularColumn("height", Int32Type.instance) |
| .addRegularColumn("score", DoubleType.instance) |
| .addStaticColumn("nickname", UTF8Type.instance) |
| .indexes(indexes.build()); |
| } |
| |
| public static TableMetadata.Builder staticSASICFMD(String ksName, String cfName) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("sensor_id", Int32Type.instance) |
| .addStaticColumn("sensor_type", UTF8Type.instance) |
| .addClusteringColumn("date", LongType.instance) |
| .addRegularColumn("value", DoubleType.instance) |
| .addRegularColumn("variance", Int32Type.instance); |
| |
| Indexes.Builder indexes = Indexes.builder(); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_sensor_type", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "sensor_type"); |
| put("mode", OnDiskIndexBuilder.Mode.PREFIX.toString()); |
| put("analyzer_class", "org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer"); |
| put("case_sensitive", "false"); |
| }})); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_value", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "value"); |
| put("mode", OnDiskIndexBuilder.Mode.PREFIX.toString()); |
| }})); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_variance", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "variance"); |
| put("mode", OnDiskIndexBuilder.Mode.PREFIX.toString()); |
| }})); |
| |
| return builder.indexes(indexes.build()); |
| } |
| |
| public static TableMetadata.Builder fullTextSearchSASICFMD(String ksName, String cfName) |
| { |
| TableMetadata.Builder builder = |
| TableMetadata.builder(ksName, cfName) |
| .addPartitionKeyColumn("song_id", UUIDType.instance) |
| .addRegularColumn("title", UTF8Type.instance) |
| .addRegularColumn("artist", UTF8Type.instance); |
| |
| Indexes.Builder indexes = Indexes.builder(); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_title", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "title"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| put("analyzer_class", "org.apache.cassandra.index.sasi.analyzer.StandardAnalyzer"); |
| put("tokenization_enable_stemming", "true"); |
| put("tokenization_locale", "en"); |
| put("tokenization_skip_stop_words", "true"); |
| put("tokenization_normalize_lowercase", "true"); |
| }})); |
| |
| indexes.add(IndexMetadata.fromSchemaMetadata(cfName + "_artist", IndexMetadata.Kind.CUSTOM, new HashMap<String, String>() |
| {{ |
| put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, SASIIndex.class.getName()); |
| put(IndexTarget.TARGET_OPTION_NAME, "artist"); |
| put("mode", OnDiskIndexBuilder.Mode.CONTAINS.toString()); |
| put("analyzer_class", "org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer"); |
| put("case_sensitive", "false"); |
| |
| }})); |
| |
| return builder.indexes(indexes.build()); |
| } |
| |
| public static CompressionParams getCompressionParameters() |
| { |
| return getCompressionParameters(null); |
| } |
| |
| public static CompressionParams getCompressionParameters(Integer chunkSize) |
| { |
| if (Boolean.parseBoolean(System.getProperty("cassandra.test.compression", "false"))) |
| return chunkSize != null ? compressionParams(chunkSize) : compressionParams(CompressionParams.DEFAULT_CHUNK_LENGTH); |
| |
| return CompressionParams.noCompression(); |
| } |
| |
| public static void cleanupAndLeaveDirs() throws IOException |
| { |
| ServerTestUtils.cleanupAndLeaveDirs(); |
| } |
| |
| public static void insertData(String keyspace, String columnFamily, int offset, int numberOfRows) |
| { |
| TableMetadata cfm = Schema.instance.getTableMetadata(keyspace, columnFamily); |
| |
| for (int i = offset; i < offset + numberOfRows; i++) |
| { |
| RowUpdateBuilder builder = new RowUpdateBuilder(cfm, FBUtilities.timestampMicros(), ByteBufferUtil.bytes("key"+i)); |
| if (cfm.clusteringColumns() != null && !cfm.clusteringColumns().isEmpty()) |
| builder.clustering(ByteBufferUtil.bytes("col"+ i)).add("val", ByteBufferUtil.bytes("val" + i)); |
| else |
| builder.add("val", ByteBufferUtil.bytes("val"+i)); |
| builder.build().apply(); |
| } |
| } |
| |
| |
| public static void cleanupSavedCaches() |
| { |
| ServerTestUtils.cleanupSavedCaches(); |
| } |
| |
| private static CompressionParams compressionParams(int chunkLength) |
| { |
| String algo = System.getProperty("cassandra.test.compression.algo", "lz4").toLowerCase(); |
| switch (algo) |
| { |
| case "deflate": |
| return CompressionParams.deflate(chunkLength); |
| case "lz4": |
| return CompressionParams.lz4(chunkLength); |
| case "snappy": |
| return CompressionParams.snappy(chunkLength); |
| case "noop": |
| return CompressionParams.noop(); |
| case "zstd": |
| return CompressionParams.zstd(chunkLength); |
| case "none": |
| return CompressionParams.noCompression(); |
| default: |
| throw new IllegalArgumentException("Invalid compression algorithm has been provided in cassandra.test.compression system property: " + algo); |
| } |
| } |
| } |