Skip to content

Commit

Permalink
Fix issue #278: add compliancemode parameter in JDBC URL if absent (#298
Browse files Browse the repository at this point in the history
)

Co-authored-by: Daniel Mallorga <[email protected]>
Co-authored-by: Jake Newton <[email protected]>
  • Loading branch information
3 people authored Jun 5, 2024
1 parent 242dce4 commit 56a5e0f
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
<version>2.2.224</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.15</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package liquibase.ext.cassandra.database;

import com.ing.data.cassandra.jdbc.CassandraDriver;
import liquibase.Scope;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.DatabaseException;

import java.net.URI;
import java.sql.Driver;
import java.util.Properties;

public class CassandraDatabaseConnection extends JdbcConnection {

@Override
public int getPriority() {
return 201;
}

@Override
public void open(String url, Driver driverObject, Properties driverProperties) throws DatabaseException {
String jdbcUrl = url;

// When using Cassandra with com.ing.data.cassandra.jdbc.CassandraDriver, it is required to specify the
// compliance mode "Liquibase" in the JDBC URL. So, do it by default when it's necessary.
if (driverObject instanceof CassandraDriver) {
try {
boolean complianceModePresent = false;
final String liquibaseComplianceModeParameter = "compliancemode=Liquibase";
// Replace the actual protocol (jdbc:cassandra:// or any other) by a valid protocol for URI
// parsing (jdbc://)
final int protocolEndIdx = jdbcUrl.indexOf("://");
final String parseableUrl = "jdbc" + jdbcUrl.substring(protocolEndIdx);
final URI jdbcUri = URI.create(parseableUrl);
final String queryPart = jdbcUri.getQuery();
if (queryPart != null) {
String[] queryParams = queryPart.split("&");
for (String queryParam : queryParams) {
if (liquibaseComplianceModeParameter.equals(queryParam)) {
complianceModePresent = true;
break;
}
}
if (!complianceModePresent) {
jdbcUrl += "&" + liquibaseComplianceModeParameter;
}
} else {
jdbcUrl += "?" + liquibaseComplianceModeParameter;
}
Scope.getCurrentScope().getLog(CassandraDatabaseConnection.class)
.info("Connecting to Cassandra using: " + jdbcUrl);
} catch (IllegalArgumentException e) {
Scope.getCurrentScope().getLog(CassandraDatabaseConnection.class)
.warning("Unable to check compliance mode in JDBC URL, connecting with configured URL. "
+ "The compliance mode might be incorrect.");
}
}

openConnection(jdbcUrl, driverObject, driverProperties);
}

void openConnection(String url, Driver driverObject, Properties driverProperties) throws DatabaseException {
super.open(url, driverObject, driverProperties);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
liquibase.ext.cassandra.database.CassandraDatabaseConnection
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package liquibase.ext.cassandra.database

import com.ing.data.cassandra.jdbc.CassandraDriver
import liquibase.exception.DatabaseException
import spock.lang.Specification
import spock.lang.Unroll

import java.sql.Driver

class CassandraDatabaseConnectionTest extends Specification {

@Unroll
def "open with #url"() {
given:
def cassandraConnection = Spy(new CassandraDatabaseConnection() {
// Overriding the real connection call, we just want to test it's called with the expected URL.
@Override
void openConnection(String jdbcUrl, Driver driverObject, Properties driverProperties) throws DatabaseException {
println("Mock open connection with URL: $jdbcUrl")
}
})
def cassandraDriver = new CassandraDriver()
def cassandraDriverProperties = new Properties()

when:
cassandraConnection.open(url, cassandraDriver, cassandraDriverProperties)

then:
1 * cassandraConnection.openConnection(expectedUrl, cassandraDriver, cassandraDriverProperties)

where:
url | expectedUrl
"jdbc:cassandra://localhost:9042/betterbotz?compliancemode=Liquibase&localdatacenter=datacenter1" | "jdbc:cassandra://localhost:9042/betterbotz?compliancemode=Liquibase&localdatacenter=datacenter1"
"jdbc:cassandra://localhost:9042/betterbotz?localdatacenter=datacenter1" | "jdbc:cassandra://localhost:9042/betterbotz?localdatacenter=datacenter1&compliancemode=Liquibase"
"jdbc:cassandra://localhost:9042/betterbotz" | "jdbc:cassandra://localhost:9042/betterbotz?compliancemode=Liquibase"

}

}

0 comments on commit 56a5e0f

Please sign in to comment.