Skip to content

Commit e8bb261

Browse files
Upgrade Cassandra Driver to 4.3.1
1 parent ef9874d commit e8bb261

File tree

12 files changed

+216
-100
lines changed

12 files changed

+216
-100
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| Version | Change |
2+
|---------|--------------------------------------------------|
3+
| 0.1.6 | Dependent on Cassandra Driver 3.2.0 and Guava 19 |
4+
| 0.2.0 | Dependent on Cassandra Driver 4.3.1 |

build.gradle

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ buildscript {
44
}
55

66
dependencies {
7-
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
8-
classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0'
7+
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
8+
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
99
}
1010
}
1111

@@ -24,20 +24,22 @@ targetCompatibility = "1.8"
2424

2525

2626
repositories {
27+
mavenLocal()
28+
maven {
29+
url = "https://oss.sonatype.org/content/repositories/snapshots/"
30+
}
2731
mavenCentral()
2832
}
2933

3034
dependencies {
31-
compile 'com.datastax.cassandra:cassandra-driver-core:3.2.0'
32-
compile 'com.google.guava:guava:19.0'
35+
compile 'com.datastax.oss:java-driver-core:4.3.1'
3336

3437
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
3538
testCompile 'org.codehaus.groovy:groovy-all:2.4.7'
36-
testCompile 'org.cassandraunit:cassandra-unit:3.0.0.1'
37-
testCompile 'cglib:cglib-nodep:3.2.4'
38-
testCompile 'org.objenesis:objenesis:2.4'
39-
testRuntime 'io.netty:netty-all:4.1.4.Final'
40-
testRuntime 'ch.qos.logback:logback-classic:1.1.7'
39+
testCompile 'org.cassandraunit:cassandra-unit:4.2.2.0-SNAPSHOT'
40+
testCompile 'cglib:cglib-nodep:3.3.0'
41+
testCompile 'org.objenesis:objenesis:3.1'
42+
testRuntime 'ch.qos.logback:logback-classic:1.2.3'
4143
}
4244

4345
jacocoTestReport {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

src/main/java/smartthings/cassandra/CassandraConnection.java

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package smartthings.cassandra;
22

3-
import com.datastax.driver.core.*;
4-
import com.google.common.base.Charsets;
5-
import com.google.common.io.Files;
3+
import com.datastax.oss.driver.api.core.*;
4+
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
5+
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
6+
import com.datastax.oss.driver.api.core.cql.ResultSet;
7+
import com.datastax.oss.driver.api.core.cql.Row;
8+
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
9+
import com.datastax.oss.driver.api.core.ssl.ProgrammaticSslEngineFactory;
10+
import com.datastax.oss.driver.shaded.guava.common.base.Charsets;
11+
import com.datastax.oss.driver.shaded.guava.common.io.Files;
612
import org.slf4j.Logger;
713
import org.slf4j.LoggerFactory;
814
import smartthings.migration.CassandraMigrationException;
@@ -14,8 +20,10 @@
1420
import java.io.File;
1521
import java.io.FileInputStream;
1622
import java.io.IOException;
23+
import java.net.InetSocketAddress;
1724
import java.security.KeyStore;
1825
import java.security.SecureRandom;
26+
import java.time.Duration;
1927
import java.util.ArrayList;
2028
import java.util.Arrays;
2129
import java.util.List;
@@ -30,11 +38,12 @@ public class CassandraConnection implements AutoCloseable {
3038
private String truststorePassword;
3139
private String keystorePath;
3240
private String keystorePassword;
33-
private Cluster cluster;
34-
private Session session;
41+
private CqlSession session;
42+
private boolean mySession = false;
3543
private String keyspace;
3644
private String host;
3745
private int port;
46+
private String localDatacenter;
3847
private String username;
3948
private String password;
4049

@@ -53,38 +62,44 @@ public CassandraConnection(MigrationParameters parameters, String ownerName) {
5362
if (session == null) {
5463
this.host = parameters.getHost();
5564
this.port = parameters.getPort();
65+
this.localDatacenter = parameters.getLocalDatacenter();
5666
this.username = parameters.getUsername();
5767
this.password = parameters.getPassword();
5868
this.truststorePassword = parameters.getTruststorePassword();
5969
this.truststorePath = parameters.getTruststorePath();
6070
this.keystorePassword = parameters.getKeystorePassword();
6171
this.keystorePath = parameters.getKeystorePath();
72+
this.mySession = true;
6273
}
6374
this.keyspace = parameters.getKeyspace();
64-
6575
}
6676

6777
public void connect() throws Exception {
6878
if (session == null) {
6979
logger.debug("Connecting to Cassandra at " + host + ":" + port);
7080

71-
QueryOptions queryOptions = new QueryOptions().setConsistencyLevel(ConsistencyLevel.QUORUM);
72-
73-
Cluster.Builder builder = Cluster.builder().addContactPoint(host).withPort(port).withMaxSchemaAgreementWaitSeconds(20).withQueryOptions(queryOptions);
81+
CqlSessionBuilder builder = CqlSession.builder()
82+
.addContactPoint(new InetSocketAddress(host, port))
83+
.withLocalDatacenter(localDatacenter)
84+
.withConfigLoader(
85+
DriverConfigLoader.programmaticBuilder()
86+
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_AGREEMENT_TIMEOUT, Duration.ofSeconds(20))
87+
.withString(DefaultDriverOption.REQUEST_CONSISTENCY, ConsistencyLevel.QUORUM.toString())
88+
.build()
89+
);
7490

7591
if (all(truststorePath, truststorePassword, keystorePath, keystorePassword)) {
7692
logger.debug("Using SSL for the connection");
7793
SSLContext sslContext = getSSLContext(truststorePath, truststorePassword, keystorePath, keystorePassword);
78-
builder.withSSL(JdkSSLOptions.builder().withSSLContext(sslContext).withCipherSuites(cipherSuites).build());
94+
builder.withSslEngineFactory(new ProgrammaticSslEngineFactory(sslContext, cipherSuites));
7995
}
8096

8197
if (username != null && password != null) {
8298
logger.debug("Using withCredentials for the connection");
83-
builder.withCredentials(username, password);
99+
builder.withAuthCredentials(username, password);
84100
}
85101

86-
cluster = builder.build();
87-
session = cluster.connect();
102+
session = builder.build();
88103
}
89104

90105
if (keyspace != null) {
@@ -103,9 +118,9 @@ public void close() {
103118
lock.unlock();
104119
}
105120

106-
if (cluster != null) {
121+
if (session != null && isMySession()) {
107122
//We don't close the connection if we were given a session
108-
cluster.close();
123+
session.close();
109124
}
110125
}
111126

@@ -135,7 +150,7 @@ public void setKeyspace(String keyspace) {
135150
}
136151

137152
public ResultSet execute(String query, Object... params) {
138-
return session.execute(query, params);
153+
return session.execute(SimpleStatement.newInstance(query, params));
139154
}
140155

141156

@@ -174,7 +189,7 @@ public void backfillMigrations() {
174189
}
175190

176191
public void setupMigration() {
177-
if (!session.getCluster().getMetadata().checkSchemaAgreement()) {
192+
if (!session.checkSchemaAgreement()) {
178193
throw new CassandraMigrationException("Migration table setup precheck: schema not in agreement");
179194
}
180195
if (!tableExists("migrations")) {
@@ -291,18 +306,18 @@ public void keepLockAlive() {
291306
public String getMigrationMd5(String fileName) {
292307
File file = new File(fileName);
293308
ResultSet result = executeWithLock("SELECT sha FROM migrations WHERE name=?", file.getName());
294-
if (result.isExhausted()) {
309+
if (result.isFullyFetched()) {
295310
return null;
296311
}
297312

298313
return result.one().getString("sha");
299314
}
300315

301-
public Session getSession() {
316+
public CqlSession getSession() {
302317
return session;
303318
}
304319

305-
public void setSession(Session session) {
320+
public void setSession(CqlSession session) {
306321
this.session = session;
307322
}
308323

@@ -377,4 +392,12 @@ public void setKeystorePassword(String keystorePassword) {
377392
public String getOwnerName() {
378393
return ownerName;
379394
}
395+
396+
/**
397+
* Returns `true` if CassandraConnection created it's own CqlSession. `false` if connection was parameterized by caller.
398+
* @return
399+
*/
400+
public boolean isMySession() {
401+
return mySession;
402+
}
380403
}

src/main/java/smartthings/cassandra/CassandraLock.java

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package smartthings.cassandra;
22

3-
import com.datastax.driver.core.*;
3+
import com.datastax.oss.driver.api.core.CqlSession;
4+
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
5+
import com.datastax.oss.driver.api.core.cql.*;
46
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
68
import smartthings.migration.CassandraMigrationException;
@@ -13,7 +15,7 @@ public class CassandraLock implements AutoCloseable {
1315
private final int ttl;
1416
private final CassandraConnection cassandraConnection;
1517
private final String owner;
16-
private final Session session;
18+
private final CqlSession session;
1719
private final PreparedStatement insertLock;
1820
private final PreparedStatement deleteLock;
1921
private final PreparedStatement selectLock;
@@ -31,22 +33,35 @@ public CassandraLock(CassandraConnection cassandraConnection, int ttl) {
3133

3234
setupTables();
3335

34-
insertLock = session.prepare("INSERT INTO databasechangelock(id, lockedby) VALUES (:lockId, :owner) IF NOT EXISTS USING TTL :ttl");
35-
insertLock.setConsistencyLevel(ConsistencyLevel.QUORUM);
36-
37-
deleteLock = session.prepare("DELETE FROM databasechangelock WHERE id = :lockId IF lockedby = :owner");
38-
deleteLock.setConsistencyLevel(ConsistencyLevel.QUORUM);
39-
40-
selectLock = session.prepare("SELECT lockedby, TTL(lockedby) AS ttl FROM databasechangelock WHERE id = :lockId");
41-
selectLock.setConsistencyLevel(ConsistencyLevel.SERIAL);
42-
43-
updateLock = session.prepare("UPDATE databasechangelock USING TTL :ttl SET lockedby = :owner WHERE id = :lockId IF lockedby = :owner");
44-
deleteLock.setConsistencyLevel(ConsistencyLevel.QUORUM);
36+
insertLock = session.prepare(
37+
SimpleStatement.newInstance("INSERT INTO databasechangelock(id, lockedby) VALUES (:lockId, :owner) IF NOT EXISTS USING TTL :ttl")
38+
.setConsistencyLevel(DefaultConsistencyLevel.QUORUM)
39+
);
40+
41+
deleteLock = session.prepare(
42+
SimpleStatement.newInstance("DELETE FROM databasechangelock WHERE id = :lockId IF lockedby = :owner")
43+
.setConsistencyLevel(DefaultConsistencyLevel.QUORUM)
44+
);
45+
46+
selectLock = session.prepare(
47+
SimpleStatement.newInstance("SELECT lockedby, TTL(lockedby) AS ttl FROM databasechangelock WHERE id = :lockId")
48+
.setConsistencyLevel(DefaultConsistencyLevel.SERIAL)
49+
);
50+
51+
updateLock = session.prepare(
52+
SimpleStatement.newInstance("UPDATE databasechangelock USING TTL :ttl SET lockedby = :owner WHERE id = :lockId IF lockedby = :ifowner")
53+
.setConsistencyLevel(DefaultConsistencyLevel.QUORUM)
54+
);
4555
}
4656

4757
public boolean tryLock() {
48-
ResultSet rs = session.execute(insertLock.bind().setInt("lockId", lockId)
49-
.setInt("ttl", ttl).setString("owner", owner));
58+
ResultSet rs = session.execute(
59+
insertLock.boundStatementBuilder()
60+
.setInt("lockId", lockId)
61+
.setInt("ttl", ttl)
62+
.setString("owner", owner)
63+
.build()
64+
);
5065
if (rs.wasApplied()) {
5166
return true;
5267
} else {
@@ -58,7 +73,12 @@ public boolean tryLock() {
5873
public void unlock() {
5974
// Only try to release lock if its mine
6075
if (isMine()) {
61-
ResultSet rs = session.execute(deleteLock.bind().setInt("lockId", lockId).setString("owner", owner));
76+
ResultSet rs = session.execute(
77+
deleteLock.boundStatementBuilder()
78+
.setInt("lockId", lockId)
79+
.setString("owner", owner)
80+
.build()
81+
);
6282
if (!rs.wasApplied()) {
6383
// if ownership was lost, should be fine, since we are relinquishing ownership
6484
if (isMine()) {
@@ -69,15 +89,25 @@ public void unlock() {
6989
}
7090

7191
public void keepAlive() {
72-
ResultSet rs = session.execute(updateLock.bind().setInt("lockId", lockId)
73-
.setInt("ttl", ttl).setString("owner", owner));
92+
ResultSet rs = session.execute(
93+
updateLock.boundStatementBuilder()
94+
.setInt("lockId", lockId)
95+
.setInt("ttl", ttl)
96+
.setString("owner", owner)
97+
.setString("ifowner", owner)
98+
.build()
99+
);
74100
if (!rs.wasApplied()) {
75101
throw new CassandraLockException("unable to keep alive lock");
76102
}
77103
}
78104

79105
public String getOwner() {
80-
Row row = session.execute(selectLock.bind().setInt("lockId", lockId)).one();
106+
Row row = session.execute(
107+
selectLock.boundStatementBuilder()
108+
.setInt("lockId", lockId)
109+
.build()
110+
).one();
81111
if (row != null) {
82112
return row.getString("lockedby");
83113
}
@@ -86,7 +116,11 @@ public String getOwner() {
86116
}
87117

88118
public int getTtl() {
89-
Row row = session.execute(selectLock.bind().setInt("lockId", lockId)).one();
119+
Row row = session.execute(
120+
selectLock.boundStatementBuilder()
121+
.setInt("lockId", lockId)
122+
.build()
123+
).one();
90124
if (row != null) {
91125
return row.getInt("ttl");
92126
}

0 commit comments

Comments
 (0)