Skip to content

Commit 9198961

Browse files
seungh0mp911de
authored andcommitted
Add support for additional table options.
- default_time_to_live - cdc - speculative_retry - memtable_flush_period_in_ms - crc_check_chance - min_index_interval - max_index_interval - read_repair Closes #1584 Original pull request: #1586 Signed-off-by: seungh0 <[email protected]>
1 parent 55f7a53 commit 9198961

File tree

6 files changed

+177
-8
lines changed

6 files changed

+177
-8
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* @author Matthew T. Adams
2828
* @author Mark Paluch
2929
* @author Mikhail Polivakha
30+
* @author Seungho Kang
3031
* @see CompactionOption
3132
* @see CompressionOption
3233
* @see CachingOption
@@ -77,7 +78,39 @@ public enum TableOption implements Option {
7778
/**
7879
* {@code gc_grace_seconds}
7980
*/
80-
GC_GRACE_SECONDS("gc_grace_seconds", Long.class, true, false, false);
81+
GC_GRACE_SECONDS("gc_grace_seconds", Long.class, true, false, false),
82+
/**
83+
* {@code default_time_to_live}
84+
*/
85+
DEFAULT_TIME_TO_LIVE("default_time_to_live", Long.class, true, false, false),
86+
/**
87+
* {@code cdc}
88+
*/
89+
CDC("cdc", Boolean.class, true, false, false),
90+
/**
91+
* {@code speculative_retry}
92+
*/
93+
SPECULATIVE_RETRY("speculative_retry", String.class, true, true, true),
94+
/**
95+
* {@code memtable_flush_period_in_ms}
96+
*/
97+
MEMTABLE_FLUSH_PERIOD_IN_MS("memtable_flush_period_in_ms", Long.class, true, false, false),
98+
/**
99+
* {@code crc_check_chance}
100+
*/
101+
CRC_CHECK_CHANCE("crc_check_chance", Double.class, true, false, false),
102+
/**
103+
* {@code min_index_interval}
104+
*/
105+
MIN_INDEX_INTERVAL("min_index_interval", Long.class, true, false, false),
106+
/**
107+
* {@code max_index_interval}
108+
*/
109+
MAX_INDEX_INTERVAL("max_index_interval", Long.class, true, false, false),
110+
/**
111+
* {@code read_repair}
112+
*/
113+
READ_REPAIR("read_repair", String.class, true, true, true);
81114

82115
private Option delegate;
83116

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
*
4444
* @author Mark Paluch
4545
* @author Mikhail Polivakha
46+
* @author Seungho Kang
4647
*/
4748
class CassandraAdminTemplateIntegrationTests extends AbstractKeyspaceCreatingIntegrationTests {
4849

@@ -66,22 +67,44 @@ private KeyspaceMetadata getKeyspaceMetadata() {
6667
return getSession().getKeyspace().flatMap(metadata::getKeyspace).get();
6768
}
6869

69-
@Test // GH-359
70+
@Test // GH-359, GH-1584
7071
void shouldApplyTableOptions() {
7172

7273
Map<String, Object> options = Map.of(TableOption.COMMENT.getName(), "This is comment for table", //
73-
TableOption.BLOOM_FILTER_FP_CHANCE.getName(), "0.3");
74+
TableOption.BLOOM_FILTER_FP_CHANCE.getName(), "0.3", //
75+
TableOption.DEFAULT_TIME_TO_LIVE.getName(), "864000", //
76+
TableOption.CDC.getName(), true, //
77+
TableOption.SPECULATIVE_RETRY.getName(), "90percentile", //
78+
TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS.getName(), "1000", //
79+
TableOption.CRC_CHECK_CHANCE.getName(), "0.9", //
80+
TableOption.MIN_INDEX_INTERVAL.getName(), "128", //
81+
TableOption.MAX_INDEX_INTERVAL.getName(), "2048", //
82+
TableOption.READ_REPAIR.getName(), "BLOCKING");
7483

7584
CqlIdentifier tableName = CqlIdentifier.fromCql("someTable");
7685
cassandraAdminTemplate.createTable(true, tableName, SomeTable.class, options);
7786

7887
TableMetadata someTable = getKeyspaceMetadata().getTables().get(tableName);
7988

8089
assertThat(someTable).isNotNull();
81-
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.COMMENT.getName())))
90+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.COMMENT.getName()))) //
8291
.isEqualTo("This is comment for table");
83-
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.BLOOM_FILTER_FP_CHANCE.getName())))
92+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.BLOOM_FILTER_FP_CHANCE.getName()))) //
8493
.isEqualTo(0.3);
94+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.DEFAULT_TIME_TO_LIVE.getName()))) //
95+
.isEqualTo(864_000);
96+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.SPECULATIVE_RETRY.getName()))) //
97+
.isEqualTo("90p");
98+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS.getName()))) //
99+
.isEqualTo(1000);
100+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.CRC_CHECK_CHANCE.getName()))) //
101+
.isEqualTo(0.9);
102+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.MIN_INDEX_INTERVAL.getName()))) //
103+
.isEqualTo(128);
104+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.MAX_INDEX_INTERVAL.getName()))) //
105+
.isEqualTo(2048);
106+
assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.READ_REPAIR.getName()))) //
107+
.isEqualTo("BLOCKING");
85108
}
86109

87110
@Test // GH-1388

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorIntegrationTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.data.cassandra.test.util.AbstractKeyspaceCreatingIntegrationTests;
3333
import org.springframework.data.util.Version;
3434

35+
import com.datastax.oss.driver.api.core.CqlIdentifier;
3536
import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata;
3637
import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata;
3738
import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata;
@@ -41,6 +42,7 @@
4142
* Integration tests tests for {@link AlterTableCqlGenerator}.
4243
*
4344
* @author Mark Paluch
45+
* @author Seungho Kang
4446
*/
4547
class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIntegrationTests {
4648

@@ -165,6 +167,39 @@ void alterTableAddCaching() {
165167
assertThat(getTableMetadata("users").getOptions().toString()).contains("caching").contains("keys").contains("NONE");
166168
}
167169

170+
@Test // GH-1584
171+
void alterTableWithAllOptionsTest() {
172+
173+
session.execute("CREATE TABLE users (user_name varchar PRIMARY KEY);");
174+
AlterTableSpecification spec = SpecificationBuilder.alterTable("users") //
175+
.with(TableOption.GC_GRACE_SECONDS, 86400L).with(TableOption.DEFAULT_TIME_TO_LIVE, 36000L)
176+
.with(TableOption.CDC, true).with(TableOption.SPECULATIVE_RETRY, "95PERCENTILE")
177+
.with(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS, 20000L).with(TableOption.CRC_CHECK_CHANCE, 0.85d)
178+
.with(TableOption.MIN_INDEX_INTERVAL, 256L).with(TableOption.MAX_INDEX_INTERVAL, 1048L)
179+
.with(TableOption.READ_REPAIR, "NONE");
180+
181+
execute(spec);
182+
183+
TableMetadata meta = getTableMetadata("users");
184+
185+
assertThat(meta.getOptions()) //
186+
.containsEntry(CqlIdentifier.fromCql(TableOption.GC_GRACE_SECONDS.getName()), 86400);
187+
assertThat(meta.getOptions()) //
188+
.containsEntry(CqlIdentifier.fromCql(TableOption.DEFAULT_TIME_TO_LIVE.getName()), 36000);
189+
assertThat(meta.getOptions()) //
190+
.containsEntry(CqlIdentifier.fromCql(TableOption.SPECULATIVE_RETRY.getName()), "95p");
191+
assertThat(meta.getOptions()) //
192+
.containsEntry(CqlIdentifier.fromCql(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS.getName()), 20000);
193+
assertThat(meta.getOptions()) //
194+
.containsEntry(CqlIdentifier.fromCql(TableOption.CRC_CHECK_CHANCE.getName()), 0.85);
195+
assertThat(meta.getOptions()) //
196+
.containsEntry(CqlIdentifier.fromCql(TableOption.MIN_INDEX_INTERVAL.getName()), 256);
197+
assertThat(meta.getOptions()) //
198+
.containsEntry(CqlIdentifier.fromCql(TableOption.MAX_INDEX_INTERVAL.getName()), 1048);
199+
assertThat(meta.getOptions()) //
200+
.containsEntry(CqlIdentifier.fromCql(TableOption.READ_REPAIR.getName()), "NONE");
201+
}
202+
168203
private void execute(AlterTableSpecification spec) {
169204
session.execute(CqlGenerator.toCql(spec));
170205
}

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorUnitTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* @author Matthew T. Adams
3636
* @author David Webb
3737
* @author Mark Paluch
38+
* @author Seungho Kang
3839
*/
3940
class AlterTableCqlGeneratorUnitTests {
4041

@@ -123,6 +124,23 @@ void alterTableAddCaching() {
123124
.isEqualTo("ALTER TABLE users WITH caching = { 'keys' : 'none', 'rows_per_partition' : '15' };");
124125
}
125126

127+
@Test // GH-1584
128+
void alterTableSetDefaultTimeToLive() {
129+
130+
AlterTableSpecification spec = SpecificationBuilder.alterTable("users")
131+
.with(TableOption.DEFAULT_TIME_TO_LIVE, 3600)
132+
.with(TableOption.CDC, true)
133+
.with(TableOption.SPECULATIVE_RETRY, "90percentile")
134+
.with(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS, 1000L)
135+
.with(TableOption.CRC_CHECK_CHANCE, 0.9)
136+
.with(TableOption.MIN_INDEX_INTERVAL, 128L)
137+
.with(TableOption.MAX_INDEX_INTERVAL, 2048L)
138+
.with(TableOption.READ_REPAIR, "BLOCKING");
139+
140+
assertThat(toCql(spec))
141+
.isEqualTo("ALTER TABLE users WITH default_time_to_live = 3600 AND cdc = true AND speculative_retry = '90percentile' AND memtable_flush_period_in_ms = 1000 AND crc_check_chance = 0.9 AND min_index_interval = 128 AND max_index_interval = 2048 AND read_repair = 'BLOCKING';");
142+
}
143+
126144
private String toCql(AlterTableSpecification spec) {
127145
return CqlGenerator.toCql(spec);
128146
}

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* @author Matthew T. Adams
3636
* @author Oliver Gierke
3737
* @author Mark Paluch
38+
* @author Seungho Kang
3839
*/
3940
class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIntegrationTests {
4041

@@ -108,4 +109,39 @@ void shouldGenerateTableInOtherKeyspace() {
108109
assertThat(person.getPartitionKey()).hasSize(1);
109110
assertThat(person.getClusteringColumns()).hasSize(1);
110111
}
112+
113+
@Test // GH-1584
114+
void shouldGenerateTableWithOptions() {
115+
116+
CreateTableSpecification spec = CreateTableSpecification.createTable("person")
117+
.partitionKeyColumn("id", DataTypes.INT) //
118+
.clusteredKeyColumn("date_of_birth", DataTypes.DATE, Ordering.ASCENDING) //
119+
.column("name", DataTypes.ASCII) //
120+
.with(TableOption.GC_GRACE_SECONDS, 86400L).with(TableOption.DEFAULT_TIME_TO_LIVE, 3600L)
121+
.with(TableOption.CDC, true).with(TableOption.SPECULATIVE_RETRY, "99PERCENTILE")
122+
.with(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS, 10000L).with(TableOption.CRC_CHECK_CHANCE, 0.9d)
123+
.with(TableOption.MIN_INDEX_INTERVAL, 128L).with(TableOption.MAX_INDEX_INTERVAL, 2048L)
124+
.with(TableOption.READ_REPAIR, "BLOCKING");
125+
126+
session.execute(CqlGenerator.toCql(spec));
127+
128+
TableMetadata meta = session.getMetadata().getKeyspace(getKeyspace()).flatMap(it -> it.getTable("person")).get();
129+
assertThat(meta.getOptions()) //
130+
.containsEntry(CqlIdentifier.fromCql(TableOption.GC_GRACE_SECONDS.getName()), 86400);
131+
132+
assertThat(meta.getOptions()) //
133+
.containsEntry(CqlIdentifier.fromCql(TableOption.DEFAULT_TIME_TO_LIVE.getName()), 3600);
134+
assertThat(meta.getOptions()) //
135+
.containsEntry(CqlIdentifier.fromCql(TableOption.SPECULATIVE_RETRY.getName()), "99p");
136+
assertThat(meta.getOptions()) //
137+
.containsEntry(CqlIdentifier.fromCql(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS.getName()), 10000);
138+
assertThat(meta.getOptions()) //
139+
.containsEntry(CqlIdentifier.fromCql(TableOption.CRC_CHECK_CHANCE.getName()), 0.9);
140+
assertThat(meta.getOptions()) //
141+
.containsEntry(CqlIdentifier.fromCql(TableOption.MIN_INDEX_INTERVAL.getName()), 128);
142+
assertThat(meta.getOptions()) //
143+
.containsEntry(CqlIdentifier.fromCql(TableOption.MAX_INDEX_INTERVAL.getName()), 2048);
144+
assertThat(meta.getOptions()) //
145+
.containsEntry(CqlIdentifier.fromCql(TableOption.READ_REPAIR.getName()), "BLOCKING");
146+
}
111147
}

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorUnitTests.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* @author David Webb
4242
* @author Mark Paluch
4343
* @author Aleksei Zotov
44+
* @author Seungho Kang
4445
*/
4546
class CreateTableCqlGeneratorUnitTests {
4647

@@ -108,7 +109,7 @@ void shouldGenerateTableOptions() {
108109
assertDoubleOption(TableOption.READ_REPAIR_CHANCE.getName(), readRepairChance, cql);
109110
}
110111

111-
@Test
112+
@Test // GH-1584
112113
void shouldGenerateMultipleOptions() {
113114

114115
CqlIdentifier name = CqlIdentifier.fromCql("timeseries_table");
@@ -121,8 +122,15 @@ void shouldGenerateMultipleOptions() {
121122
Double readRepairChance = 0.5;
122123
Double dcLocalReadRepairChance = 0.7;
123124
Double bloomFilterFpChance = 0.001;
124-
Boolean replcateOnWrite = Boolean.FALSE;
125125
Long gcGraceSeconds = 600l;
126+
Long defaultTimeToLive = 864_00L;
127+
Boolean cdc = Boolean.TRUE;
128+
String speculative_retry = "99percentile";
129+
Long memtableFlushPeriodInMs = 600L;
130+
Double crcCheckChance = 0.9;
131+
Long maxIndexInterval = 2048L;
132+
Long minIndexInterval = 128L;
133+
126134
String comment = "This is My Table";
127135
Map<Option, Object> compactionMap = new LinkedHashMap<>();
128136
Map<Option, Object> compressionMap = new LinkedHashMap<>();
@@ -146,7 +154,11 @@ void shouldGenerateMultipleOptions() {
146154
.with(TableOption.COMPRESSION, compressionMap).with(TableOption.BLOOM_FILTER_FP_CHANCE, bloomFilterFpChance)
147155
.with(TableOption.CACHING, cachingMap).with(TableOption.COMMENT, comment)
148156
.with(TableOption.DCLOCAL_READ_REPAIR_CHANCE, dcLocalReadRepairChance)
149-
.with(TableOption.GC_GRACE_SECONDS, gcGraceSeconds);
157+
.with(TableOption.GC_GRACE_SECONDS, gcGraceSeconds).with(TableOption.DEFAULT_TIME_TO_LIVE, defaultTimeToLive)
158+
.with(TableOption.CDC, cdc).with(TableOption.SPECULATIVE_RETRY, speculative_retry)
159+
.with(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS, memtableFlushPeriodInMs)
160+
.with(TableOption.CRC_CHECK_CHANCE, crcCheckChance).with(TableOption.MAX_INDEX_INTERVAL, maxIndexInterval)
161+
.with(TableOption.MIN_INDEX_INTERVAL, minIndexInterval).with(TableOption.READ_REPAIR, "BLOCKING");
150162

151163
String cql = CqlGenerator.toCql(table);
152164

@@ -159,6 +171,14 @@ void shouldGenerateMultipleOptions() {
159171
assertDoubleOption(TableOption.BLOOM_FILTER_FP_CHANCE.getName(), bloomFilterFpChance, cql);
160172
assertStringOption(TableOption.COMMENT.getName(), comment, cql);
161173
assertLongOption(TableOption.GC_GRACE_SECONDS.getName(), gcGraceSeconds, cql);
174+
assertLongOption(TableOption.DEFAULT_TIME_TO_LIVE.getName(), defaultTimeToLive, cql);
175+
assertBooleanOption(TableOption.CDC.getName(), cdc, cql);
176+
assertStringOption(TableOption.SPECULATIVE_RETRY.getName(), speculative_retry, cql);
177+
assertLongOption(TableOption.MEMTABLE_FLUSH_PERIOD_IN_MS.getName(), memtableFlushPeriodInMs, cql);
178+
assertDoubleOption(TableOption.CRC_CHECK_CHANCE.getName(), crcCheckChance, cql);
179+
assertLongOption(TableOption.MAX_INDEX_INTERVAL.getName(), maxIndexInterval, cql);
180+
assertLongOption(TableOption.MIN_INDEX_INTERVAL.getName(), minIndexInterval, cql);
181+
assertStringOption(TableOption.READ_REPAIR.getName(), "BLOCKING", cql);
162182
}
163183

164184
@Test // DATACASS-518
@@ -254,6 +274,10 @@ private static void assertLongOption(String name, Long value, String cql) {
254274
assertThat(cql).contains(name + " = " + value);
255275
}
256276

277+
private static void assertBooleanOption(String name, Boolean value, String cql) {
278+
assertThat(cql).contains(name + " = " + value);
279+
}
280+
257281
/**
258282
* Asserts that the read repair change is set properly
259283
*/

0 commit comments

Comments
 (0)