Skip to content

Commit c182aa0

Browse files
author
Michael Karsten
committed
CASSJAVA-89 fix: support schema options that changed in Cassandra 5.0
1 parent 7982f41 commit c182aa0

File tree

4 files changed

+373
-22
lines changed

4 files changed

+373
-22
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package com.datastax.oss.driver.querybuilder;
19+
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
import com.datastax.oss.driver.api.core.CqlSession;
23+
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
24+
import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata;
25+
import com.datastax.oss.driver.api.core.type.DataTypes;
26+
import com.datastax.oss.driver.api.querybuilder.SchemaBuilder;
27+
import com.datastax.oss.driver.api.testinfra.ccm.CcmRule;
28+
import com.datastax.oss.driver.api.testinfra.requirement.BackendRequirement;
29+
import com.datastax.oss.driver.api.testinfra.requirement.BackendType;
30+
import com.datastax.oss.driver.api.testinfra.session.SessionRule;
31+
import com.datastax.oss.driver.api.testinfra.session.SessionUtils;
32+
import com.datastax.oss.driver.categories.ParallelizableTests;
33+
import java.time.Duration;
34+
import org.junit.After;
35+
import org.junit.ClassRule;
36+
import org.junit.Test;
37+
import org.junit.experimental.categories.Category;
38+
import org.junit.rules.RuleChain;
39+
import org.junit.rules.TestRule;
40+
41+
@Category(ParallelizableTests.class)
42+
public class RelationOptionsIT {
43+
private static final CcmRule CCM_RULE = CcmRule.getInstance();
44+
45+
private static final SessionRule<CqlSession> SESSION_RULE =
46+
SessionRule.builder(CCM_RULE)
47+
.withConfigLoader(
48+
SessionUtils.configLoaderBuilder()
49+
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
50+
.build())
51+
.build();
52+
53+
@ClassRule
54+
public static final TestRule CHAIN = RuleChain.outerRule(CCM_RULE).around(SESSION_RULE);
55+
56+
@After
57+
public void clearTable() {
58+
SESSION_RULE.session().execute("DROP TABLE relation_options");
59+
}
60+
61+
@Test
62+
@BackendRequirement(
63+
type = BackendType.CASSANDRA,
64+
minInclusive = "3.0",
65+
description = "CRC check chance was moved to top level table in Cassandra 3.0")
66+
public void should_create_table_with_crc_check_chance() {
67+
try (CqlSession session = session()) {
68+
session.execute(
69+
SchemaBuilder.createTable("relation_options")
70+
.withPartitionKey("id", DataTypes.INT)
71+
.withColumn("name", DataTypes.TEXT)
72+
.withColumn("age", DataTypes.INT)
73+
.withCRCCheckChance(0.8)
74+
.build());
75+
KeyspaceMetadata keyspaceMetadata =
76+
session
77+
.getMetadata()
78+
.getKeyspace(SESSION_RULE.keyspace())
79+
.orElseThrow(AssertionError::new);
80+
String describeOutput = keyspaceMetadata.describeWithChildren(true).trim();
81+
82+
assertThat(describeOutput).contains("crc_check_chance = 0.8");
83+
}
84+
}
85+
86+
@Test
87+
@BackendRequirement(
88+
type = BackendType.CASSANDRA,
89+
minInclusive = "5.0",
90+
description = "chunk_length_kb was renamed to chunk_length_in_kb in Cassandra 5.0")
91+
public void should_create_table_with_chunk_length_in_kb() {
92+
try (CqlSession session = session()) {
93+
session.execute(
94+
SchemaBuilder.createTable("relation_options")
95+
.withPartitionKey("id", DataTypes.INT)
96+
.withColumn("name", DataTypes.TEXT)
97+
.withColumn("age", DataTypes.INT)
98+
.withLZ4Compression(4096)
99+
.build());
100+
KeyspaceMetadata keyspaceMetadata =
101+
session
102+
.getMetadata()
103+
.getKeyspace(SESSION_RULE.keyspace())
104+
.orElseThrow(AssertionError::new);
105+
String describeOutput = keyspaceMetadata.describeWithChildren(true).trim();
106+
107+
assertThat(describeOutput)
108+
.contains("'class':'org.apache.cassandra.io.compress.LZ4Compressor'");
109+
assertThat(describeOutput).contains("'chunk_length_in_kb':'4096'");
110+
}
111+
}
112+
113+
@Test
114+
@BackendRequirement(
115+
type = BackendType.CASSANDRA,
116+
maxExclusive = "5.0",
117+
description = "chunk_length_kb was renamed to chunk_length_in_kb in Cassandra 5.0")
118+
public void should_create_table_with_deprecated_options() {
119+
try (CqlSession session = session()) {
120+
session.execute(
121+
SchemaBuilder.createTable("relation_options")
122+
.withPartitionKey("id", DataTypes.INT)
123+
.withColumn("name", DataTypes.TEXT)
124+
.withColumn("age", DataTypes.INT)
125+
.withLZ4Compression(4096, 1.0)
126+
.build());
127+
KeyspaceMetadata keyspaceMetadata =
128+
session
129+
.getMetadata()
130+
.getKeyspace(SESSION_RULE.keyspace())
131+
.orElseThrow(AssertionError::new);
132+
String describeOutput = keyspaceMetadata.describeWithChildren(true).trim();
133+
134+
assertThat(describeOutput)
135+
.contains("'class':'org.apache.cassandra.io.compress.LZ4Compressor'");
136+
assertThat(describeOutput).contains("'chunk_length_kb':'4096'");
137+
assertThat(describeOutput).contains("'crc_check_chance':'0.8'");
138+
}
139+
}
140+
141+
@SuppressWarnings("unchecked")
142+
private CqlSession session() {
143+
return (CqlSession)
144+
SessionUtils.baseBuilder()
145+
.addContactEndPoints(CCM_RULE.getContactPoints())
146+
.withKeyspace(SESSION_RULE.keyspace())
147+
.build();
148+
}
149+
}

query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/schema/RelationOptions.java

Lines changed: 104 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ default SelfT withCDC(boolean enabled) {
5858
return withOption("cdc", enabled);
5959
}
6060

61+
/**
62+
* Defines the crc check chance.
63+
*
64+
* <p>Note that using this option with a version of Apache Cassandra less than 3.0 will raise a
65+
* syntax error.
66+
*/
67+
@NonNull
68+
@CheckReturnValue
69+
default SelfT withCRCCheckChance(double crcCheckChance) {
70+
return withOption("crc_check_chance", crcCheckChance);
71+
}
72+
6173
/**
6274
* Defines the caching criteria.
6375
*
@@ -97,22 +109,32 @@ default SelfT withCompaction(@NonNull CompactionStrategy<?> compactionStrategy)
97109
}
98110

99111
/**
100-
* Configures compression using the LZ4 algorithm with the given chunk length and crc check
101-
* chance.
102-
*
103-
* @see #withCompression(String, int, double)
112+
* @deprecated This method only exists for backward compatibility. Will not work with Apache
113+
* Cassandra 5.0 or later. Use {@link #withLZ4Compression(int)} instead.
104114
*/
115+
@Deprecated
105116
@NonNull
106117
@CheckReturnValue
107118
default SelfT withLZ4Compression(int chunkLengthKB, double crcCheckChance) {
108119
return withCompression("LZ4Compressor", chunkLengthKB, crcCheckChance);
109120
}
110121

122+
/**
123+
* Configures compression using the LZ4 algorithm with the given chunk length.
124+
*
125+
* @see #withCompression(String, int)
126+
*/
127+
@NonNull
128+
@CheckReturnValue
129+
default SelfT withLZ4Compression(int chunkLengthKB) {
130+
return withCompression("LZ4Compressor", chunkLengthKB);
131+
}
132+
111133
/**
112134
* Configures compression using the LZ4 algorithm using the default configuration (64kb
113-
* chunk_length, and 1.0 crc_check_chance).
135+
* chunk_length).
114136
*
115-
* @see #withCompression(String, int, double)
137+
* @see #withCompression(String, int)
116138
*/
117139
@NonNull
118140
@CheckReturnValue
@@ -121,22 +143,57 @@ default SelfT withLZ4Compression() {
121143
}
122144

123145
/**
124-
* Configures compression using the Snappy algorithm with the given chunk length and crc check
125-
* chance.
146+
* Configures compression using the Zstd algorithm with the given chunk length.
126147
*
127-
* @see #withCompression(String, int, double)
148+
* @see #withCompression(String, int)
128149
*/
129150
@NonNull
130151
@CheckReturnValue
152+
default SelfT withZstdCompression(int chunkLengthKB) {
153+
return withCompression("ZstdCompressor", chunkLengthKB);
154+
}
155+
156+
/**
157+
* Configures compression using the Zstd algorithm using the default configuration (64kb
158+
* chunk_length).
159+
*
160+
* @see #withCompression(String, int)
161+
*/
162+
@NonNull
163+
@CheckReturnValue
164+
default SelfT withZstdCompression() {
165+
return withCompression("ZstdCompressor");
166+
}
167+
168+
/**
169+
* @deprecated This method only exists for backward compatibility. Will not work with Apache
170+
* Cassandra 5.0 or later due to removal of deprecated table properties (<a
171+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18742">CASSANDRA-18742</a>). Use
172+
* {@link #withSnappyCompression(int)} instead.
173+
*/
174+
@Deprecated
175+
@NonNull
176+
@CheckReturnValue
131177
default SelfT withSnappyCompression(int chunkLengthKB, double crcCheckChance) {
132178
return withCompression("SnappyCompressor", chunkLengthKB, crcCheckChance);
133179
}
134180

181+
/**
182+
* Configures compression using the Snappy algorithm with the given chunk length.
183+
*
184+
* @see #withCompression(String, int)
185+
*/
186+
@NonNull
187+
@CheckReturnValue
188+
default SelfT withSnappyCompression(int chunkLengthKB) {
189+
return withCompression("SnappyCompressor", chunkLengthKB);
190+
}
191+
135192
/**
136193
* Configures compression using the Snappy algorithm using the default configuration (64kb
137-
* chunk_length, and 1.0 crc_check_chance).
194+
* chunk_length).
138195
*
139-
* @see #withCompression(String, int, double)
196+
* @see #withCompression(String, int)
140197
*/
141198
@NonNull
142199
@CheckReturnValue
@@ -145,22 +202,34 @@ default SelfT withSnappyCompression() {
145202
}
146203

147204
/**
148-
* Configures compression using the Deflate algorithm with the given chunk length and crc check
149-
* chance.
150-
*
151-
* @see #withCompression(String, int, double)
205+
* @deprecated This method only exists for backward compatibility. Will not work with Apache
206+
* Cassandra 5.0 or later due to removal of deprecated table properties (<a
207+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18742">CASSANDRA-18742</a>). Use
208+
* {@link #withDeflateCompression(int)} instead.
152209
*/
210+
@Deprecated
153211
@NonNull
154212
@CheckReturnValue
155213
default SelfT withDeflateCompression(int chunkLengthKB, double crcCheckChance) {
156214
return withCompression("DeflateCompressor", chunkLengthKB, crcCheckChance);
157215
}
158216

217+
/**
218+
* Configures compression using the Deflate algorithm with the given chunk length.
219+
*
220+
* @see #withCompression(String, int)
221+
*/
222+
@NonNull
223+
@CheckReturnValue
224+
default SelfT withDeflateCompression(int chunkLengthKB) {
225+
return withCompression("DeflateCompressor", chunkLengthKB);
226+
}
227+
159228
/**
160229
* Configures compression using the Deflate algorithm using the default configuration (64kb
161-
* chunk_length, and 1.0 crc_check_chance).
230+
* chunk_length).
162231
*
163-
* @see #withCompression(String, int, double)
232+
* @see #withCompression(String, int)
164233
*/
165234
@NonNull
166235
@CheckReturnValue
@@ -170,13 +239,13 @@ default SelfT withDeflateCompression() {
170239

171240
/**
172241
* Configures compression using the given algorithm using the default configuration (64kb
173-
* chunk_length, and 1.0 crc_check_chance).
242+
* chunk_length).
174243
*
175244
* <p>Unless specifying a custom compression algorithm implementation, it is recommended to use
176245
* {@link #withLZ4Compression()}, {@link #withSnappyCompression()}, or {@link
177246
* #withDeflateCompression()}.
178247
*
179-
* @see #withCompression(String, int, double)
248+
* @see #withCompression(String, int)
180249
*/
181250
@NonNull
182251
@CheckReturnValue
@@ -185,19 +254,32 @@ default SelfT withCompression(@NonNull String compressionAlgorithmName) {
185254
}
186255

187256
/**
188-
* Configures compression using the given algorithm, chunk length and crc check chance.
257+
* Configures compression using the given algorithm, chunk length.
189258
*
190259
* <p>Unless specifying a custom compression algorithm implementation, it is recommended to use
191260
* {@link #withLZ4Compression()}, {@link #withSnappyCompression()}, or {@link
192261
* #withDeflateCompression()}.
193262
*
194263
* @param compressionAlgorithmName The class name of the compression algorithm.
195264
* @param chunkLengthKB The chunk length in KB of compression blocks. Defaults to 64.
196-
* @param crcCheckChance The probability (0.0 to 1.0) that checksum will be checked on each read.
197-
* Defaults to 1.0.
198265
*/
199266
@NonNull
200267
@CheckReturnValue
268+
default SelfT withCompression(@NonNull String compressionAlgorithmName, int chunkLengthKB) {
269+
return withOption(
270+
"compression",
271+
ImmutableMap.of("class", compressionAlgorithmName, "chunk_length_in_kb", chunkLengthKB));
272+
}
273+
274+
/**
275+
* @deprecated This method only exists for backward compatibility. Will not work with Apache
276+
* Cassandra 5.0 or later due to removal of deprecated table properties (<a
277+
* href="https://issues.apache.org/jira/browse/CASSANDRA-18742">CASSANDRA-18742</a>). Use
278+
* {@link #withCompression(String, int)} instead.
279+
*/
280+
@NonNull
281+
@CheckReturnValue
282+
@Deprecated
201283
default SelfT withCompression(
202284
@NonNull String compressionAlgorithmName, int chunkLengthKB, double crcCheckChance) {
203285
return withOption(

0 commit comments

Comments
 (0)