Giter Club home page Giter Club logo

cassandra-jdbc-wrapper's People

Contributors

clun avatar danil9966 avatar kornilova203 avatar likdan avatar maximevw avatar mjok avatar msmygit avatar stefanofornari avatar sualeh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cassandra-jdbc-wrapper's Issues

Cassandra liquibase usage

Hi, I tested this for use with Cassandra liquibase. It installs, but fails on a dummy project. See my post here

liquibase.exception.DatabaseException: Error executing SQL SELECT COUNT(*) FROM liquibase.DATABASECHANGELOGLOCK: Method was called on a closed Statement.

I did have the compliancemode turned on (the keyspace is also called liquibase: "jdbc:cassandra://<URL>/liquibase?localdatacenter=cassandra&compliancemode=Liquibase")

Is this used in production anywhere? I couldn't make sense of the databasechangeloglock error

Handle multiple host:port in the JDBC connection string

Discussed in #40

Originally posted by stefanofornari November 13, 2023
Hello, it is mentioned several time the connection string is something like:

jdbc:cassandra://host1--host2--host3:9042/keyspace

What if nodes have different ports? can the below be used?

jdbc:cassandra://host1:port1--host2:port2--host3:port3/keyspace

[Question] - Does improving Dbaas support would make sense ?

Technical Context

As of today to use the DBAAS component on this Cassandra JDBC wrapper you need to provide a Secure connect bundle ZIP. Now using a library like the astra-sdk-devops it is possible to download this library on the fly and simply the URL.

Astra JDBC Wrapper

The work has been done in the following repository
https://github.com/DataStax-Examples/astra-jdbc-connector/tree/main

Ending with url than looks like:

jdbc:astra://<db_name>/<keyspace>?token=<token>

Outcomes

This issue is open for multiple purposes:

  • Bring awareness to the ING Team and have their acknowledgment that we explicit mentioned them everywhere and that the component is fully open source and free as the Apache License 2.

  • Bring attention to awesome-astra.github.io to see all cool integrations available for Cassandra (/Astra)

  • Asked the question should those repositories be merged (I do not see an need here).

Can't set complianceMode="Liquibase" when create CassandraDataSource for cassandra-liquibase extension

Currently i'm using cassandra-jdbc-wrapper 4.12.0 and cassandra-liquibase 4.28.0. DefaultOptionSet always returns 0 in getSQLUpdateResponse() method and to avoid such behaviour i've been told to use compliancemode=Liquibase parameter in connection url. liquibase/liquibase-cassandra#212 (comment)
it would be helpful to have this, because it just doesnt work otherwise, if we configure liquibase inside java app

Does this driver supports SSL ?

Does this driver supports SSL ?
if yes where I need to pass the keystore and truststore information and what is the connection for enabling the SSL ?

Impossible to connect to Liquibase Cassandra

Hello,

I tried to use the latest version of this driver (4.10.2) with the latest version of liquibase-core and liquibase-cassandra (4.25.0). I use SBT (1.9.7) and Java 11.

I haven't managed to replace the old datastax driver with the new one.

Previously, settings were made as follows:

val database = DatabaseFactory.getInstance.findCorrectDatabaseImplementation(
   new JdbcConnection(
      new Driver().connect(
          s"jdbc:cassandra://localhost:${cqlPort.toString}/$keyspace;DefaultKeyspace=$keyspace",
          new Properties()
     )
  )
)
    
new Liquibase(
  changeLog.getAbsolutePath,
  new FileSystemResourceAccessor(new File("/")),
  database
)

After swapping with the ING driver, I updated the above code like this (https://docs.liquibase.com/workflows/liquibase-community/using-liquibase-java-api.html):

val connection: Connection = DriverManager.getConnection(
        s"jdbc:cassandra://localhost:${cqlPort.toString}/$keyspace?compliancemode=Liquibase&localdatacenter=dc1&requesttimeout=10000"
 )

new Liquibase(
  changeLog.getAbsolutePath,
  new FileSystemResourceAccessor(new File("/")),
  DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection))
)

And I'm getting the error:

java.lang.ClassCastException: class liquibase.database.jvm.JdbcConnection cannot be cast to class com.ing.data.cassandra.jdbc.CassandraConnection (liquibase.database.jvm.JdbcConnection and com.ing.data.cassandra.jdbc.CassandraConnection are in unnamed module of loader sbt.internal.LayeredClassLoader @20850fc2)

Let me know if you need more details.
Thanks in advance

com.datastax.oss.driver.api.core.NoNodeAvailableException: No node was available to execute the query

I am trying to use the new version of liquibase-cassandra which uses this driver. However I keep getting the com.datastax.oss.driver.api.core.NoNodeAvailableException: No node was available to execute the query So created a small snippet only with the driver which also results in the same error.

public class HelloCassandra {
    public static void main(final String[] args) throws SQLException {
        // Used driver: com.ing.data.cassandra.cassandra.jdbc.CassandraDriver
        final String url = "jdbc:cassandra://node1.dc1-llds-1-tst.cassandra.xx:9142/contacting?configfile=/Users/BO55NK/IdeaProjects/untitled/src/main/resources/test.conf";
       
        final Connection connection = DriverManager.getConnection(url);
        connection.prepareStatement("Select * from contacting.contacting_configs").executeQuery();
    }
}

My test.conf looks like this

datastax-java-driver {

  basic.load-balancing-policy {
    class = DefaultLoadBalancingPolicy
    local-datacenter: DC1
  }
  basic.session-keyspace = "contacting"
  basic.request {
    timeout = 20 seconds
    consistency = LOCAL_ONE

  }
  advanced.auth-provider {
    class = PlainTextAuthProvider
    username: xxx_owner
    password: "xxxxxxx"
  }
  advanced.ssl-engine-factory {
    class = DefaultSslEngineFactory
    hostname-validation = false

    truststore-path = /resources/http-trust.jks
    truststore-password = xxxx
  }
}

What could I be possibly missing ?

Driver redirecting to internal IP ?

Hello,
I have a configuration with two nodes with replication factor 2; they are behind a router with NAT. From the outside, I want to access to one of the two nodes only (for now), therefore I configured the DNS to point to the router and the router NATs it to node 1:

image

When from the outside I try to access the node, it seems the driver tries to use the internal IP (node1_local_ip) and therefore it fails:

using store jdbc:cassandra://cassandra.mydm.com:9042/uzzstore?localdatacenter=datacenter1
DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.17.0
Adding handler to invalidate cached prepared statements on type changes
Using native clock for microsecond precision
[s0|/node1_local_ip:9042  Error while opening new channel (ConnectionInitException: [s0|connecting...] Protocol initialization request, step 1 (STARTUP {CQL_VERSION=3.0.0, DRIVER_NAME=DataStax Java driver for Apache Cassandra(R), DRIVER_VERSION=4.17.0, CLIENT_ID=58789f9d-9a41-4104-af90-5d545a7eea8d}): failed to send request (java.nio.channels.NotYetConnectedException))
Connected to cluster: Uzz, with session: s0
Datacenter: datacenter1; Host: cassandra.mydm.com/<unresolved>:9042; Rack: rack1
Datacenter: datacenter1; Host: /node2_local_ip:9042; Rack: rack1
Node: cassandra.mydm.com/<unresolved>:9042 runs Cassandra v.3.0.8
[s0|/node1_local_ip Error while opening new channel (ConnectionInitException: [s0|connecting...] Protocol initialization request, step 1 (STARTUP {CQL_VERSION=3.0.0, DRIVER_NAME=DataStax Java driver for Apache Cassandra(R), DRIVER_VERSION=4.17.0, CLIENT_ID=58789f9d-9a41-4104-af90-5d545a7eea8d}): failed to send request (java.nio.channels.NotYetConnectedException))

As I see, it tries to use the local ip of the second node

Is that the intended behaviour? Is there any workaround?

ERRATA: the second node is listening to the standard port 9042, not 9142 as in the picture...

Driver not found?

Hello, usually a JDBC driver is loaded from its URL and should not be specified. I am using ORMLite in my project and trying to use the cassandra jdbc I get this error:

 Caused by: java.lang.IllegalArgumentException: Unknown database-type url part 'cassandra' in: jdbc:cassandra://192.168.1.100:9042/keyspacetest?localdatacenter=DC1
        at com.j256.ormlite.jdbc.db.DatabaseTypeUtils.createDatabaseType(DatabaseTypeUtils.java:55)
        at com.j256.ormlite.jdbc.BaseJdbcConnectionSource.initialize(BaseJdbcConnectionSource.java:101)
        at com.j256.ormlite.jdbc.JdbcConnectionSource.<init>(JdbcConnectionSource.java:104)
        at com.j256.ormlite.jdbc.JdbcConnectionSource.<init>(JdbcConnectionSource.java:47)

Same thing if I use it in DBEaver without explicitly providing the driver.

Am I missing something?

Liquibase cassandra fails

@maximevw Firstly Thanks for the release 4.10.2 which fixed my previous issue.

However I now encounter a new one . When I run it I now get

Unexpected error running Liquibase: line 1:53 no viable alternative at input '(' (... TABLE contacting.DATABASECHANGELOG (ID [VARCHAR](...) [Failed SQL: (0) CREATE TABLE contacting.DATABASECHANGELOG (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED datetime NOT NULL, ORDEREXECUTED INT NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35), DESCRIPTION VARCHAR(255), COMMENTS VARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20), CONTEXTS VARCHAR(255), LABELS VARCHAR(255), DEPLOYMENT_ID VARCHAR(10))]

I did read about the compliance mode and #25 . I am not sure if all liquibase users should use that compliance mode. I tried with that as well but no luck. Any pointers ?

Can't connect to Astra with "Connection was established but closed as invalid"

Hi,

I'm using the latest JDBC driver and trying to connect to Astra. I was trying to connect to Vector and general ones.

URL:

jdbc:cassandra://dbaas/another_datagrip?user=token&password=AstraCS:$$TOKEN$$&secureconnectbundle=/Users/vasilii.chernov/Projects/secure-connect-another-datagrip.zip

Test Connection
image

Log chunk

2024-06-27 18:27:29,131 [14160048]   INFO - #c.i.e.r.RemoteProcessSupport - SSL MODE is REQUIRE
2024-06-27 18:27:29,131 [14160048]   INFO - #c.i.e.r.RemoteProcessSupport - Setting `verifyServerCertificate` to `false`
2024-06-27 18:27:29,136 [14160053]   WARN - #c.i.e.r.RemoteProcessSupport - SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
2024-06-27 18:27:29,136 [14160053]   WARN - #c.i.e.r.RemoteProcessSupport - SLF4J: Defaulting to no-operation (NOP) logger implementation
2024-06-27 18:27:29,136 [14160053]   WARN - #c.i.e.r.RemoteProcessSupport - SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2024-06-27 18:27:32,029 [14162946]   INFO - #c.i.e.r.RemoteProcessSupport - Driver: Cassandra JDBC Driver 4.12.0-DataGrip-patch-2
2024-06-27 18:27:32,031 [14162948]   INFO - #c.i.e.r.RemoteProcessSupport - getDatabaseProductName: Cassandra
2024-06-27 18:27:32,171 [14163088]   INFO - #c.i.e.r.RemoteProcessSupport - release_version: 4.0.0.6816
2024-06-27 18:27:32,174 [14163091]   INFO - #c.i.e.r.RemoteProcessSupport - Detected: CASSANDRA 4.0.0.6816
2024-06-27 18:27:32,261 [14163178]   INFO - #c.i.d.c.JdbcEngineUtils - Connection is invalid

Is there any way to get more details to identify the root cause?

Return all supported properties from CassandraDriver.getPropertyInfo

DB tools like DataGrip use Driver.getPropertyInfo to display all possible connection parameters to user. Without this it's tricky for users to figure out what parameters are supported for driver.
There is a number of supported parameters in SessionHolder.createSession but they are not returned from Driver.getPropertyInfo

If a column value contains a semicolon (`;`), it cannot be processed correctly

In the code, the query is split using a semicolon (;). Therefore, if a column value contains a semicolon, it could potentially break the query.
This issue was identified in the ticket below.
liquibase/liquibase-cassandra#258

Liquibase inserts strings separated by semicolons in the description into DATABASECHANGELOG table when there are multiple changes within a changeset.
However, it can't process correctly since query is split in the middle.

error messages

Unexpected error running Liquibase: line 1:282 mismatched character '<EOF>' expecting ''' [Failed SQL: (0) INSERT INTO test.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('create-tables', 'test', 'changelog.yml', 1703112425259, 1, '9:abd6cfa9eea355da8b0d16523bcc5115', 'sql; sql', '', 'EXECUTED', NULL, NULL, '4.25.0', '3112424168')]

Caused by: java.sql.SQLTransientException: com.datastax.oss.driver.api.core.servererrors.SyntaxError: line 1:282 mismatched character '<EOF>' expecting '''

cc @maximevw 

Observed data loss while fetching records from Cassandra through Cassandra JDBC

Table Structure : testkeyspace.productInfo (productID, productName, timestamp, price) - Partition key column in the above table is “productId”. - table -> testkeyspace.productInfo consists of 10k records

Test Case

Test consists of two Java applications
Application 1 -> Writes data to Cassandra table (testkeyspace.productInfo)
Application 2 -> Reads from Cassandra table (testkeyspace.productInfo) continuously with 5 seconds interval
Partition Key (productID) is unique for all records. Hence, Number of partitions = Number of records in table

How data is read from Cassandra table? (Read Pattern)

  1. Initially, "SELECT *" is issued to Cassandra table with the help of Cassandra JDBC
  2. Latest Timestamp (lastNotedTimestamp) of the fetched records is noted from the timestamp column of the table
  3. The subsequent "SELECT *" are issued with a WHERE condition of timestamp > lastNotedTimestamp
  4. Step 2 and 3 are repeated until application kill.

Issue

  1. While Step 4 is executed in parallel with the write application, few random records are missing in the ResultSet returned from the JDBC call.
  2. While Step 4 is executed after write application has completed its task, records are not missed and the fetching is successful.

Note: Above mentioned issue is applicable even when using a numeric-based column in the WHERE clause of the select query.

It's tested and observed in the single node cluster.

VARBINARY not supported and issue with BINARY

Hello,

the following case does not work with cassandra-jdbc-driver:


// create table atable(id blob primary key)
Connection c = DriverManager.getConnection(DB, null, null);
PreparedStatement s = c.prepareStatement("INSERT INTO atable (id) VALUES (?)");
final byte[] ID1 = new byte[] {
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
s.setObject(1, ID1, Types.VARBINARY);
s.executeUpdate();

throwing the errror:

java.sql.SQLException: Unsupported SQL type: -3
	at com.ing.data.cassandra.jdbc.CassandraPreparedStatement.setObject(CassandraPreparedStatement.java:662)
	at com.ing.data.cassandra.jdbc.CassandraPreparedStatement.setObject(CassandraPreparedStatement.java:538)

I think the issue is in setObject()

public final void setObject(final int parameterIndex, final Object x, final int targetSqlType,

In particular, in the block handling Types.BINARYY

case Types.BINARY:
final byte[] array = new byte[((ByteArrayInputStream) x).available()];
try {
((ByteArrayInputStream) x).read(array);
} catch (final IOException e) {
LOG.warn("Exception while setting object of BINARY type.", e);
}
this.boundStatement = this.boundStatement.setByteBuffer(parameterIndex - 1, ByteBuffer.wrap(array));
break;

As per the JDBC documentation, the method should perform a conversion taking into account multiple cases for the input type. However I agree to take a simpler approach at least to start with, but I see to main issues with the current implementation:

  1. it does not handle Types.VARBINARY (therefore the exception); this can be easily fixed handling it as a synonym of BINARY
  2. it assumes the object to be an InpuStream while instead it can be any type. Leaving apart handling Ref, Blob, Clob, NClob, Struct, java.net.URL, and Array, it should support at least the case the object is a byte array.

I would propose something like this:

case Types.BINARY:
case Types.VARBINARY:
    byte[] array = null;
    if (x instanceof ByteArrayInputStream) {
        array = new byte[((ByteArrayInputStream) x).available()];
        try {
            ((ByteArrayInputStream) x).read(array);
        } catch (final IOException e) {
            LOG.warn("Exception while setting object of BINARY type.", e);
        }
    } else if (x instanceof byte[]) {
        array = (byte[])x;
    } else {
        throw new SQLException("Unsupported parameter type: " + x.getClass());
    }
    this.boundStatement = this.boundStatement.setByteBuffer(parameterIndex - 1, ByteBuffer.wrap(array));
    break;

I won't be able to provide a PR due to the need of a dockered Cassandra... :(

Assertion error checking

CResultSetMetaData makes an assumption that all table names are CQL identifiers. However, for some metadata resultset, table names may be empty strings. This can cause an assertion error in CResultSetMetaData::isSearchable. Perhaps the flatmap can check for empty table names, and do something different to prevent the assertion error? The error comes from KeyspaceMetadata::getTableCqlIdentifier::fromCqlStrings::needsDoubleQuotes.

CassandraResultSet.findColumn() returns a 0 based index (as opposed to 1-based index)

Given a simple table like size(id varchar, size bigint), run the following code (with proper connectionstring)

Connection c = DriverManager.getConnection("...", null, null);
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT \"id\" FROM \"size\" WHERE \"id\" IN ('100')");
System.out.println(rs.findColumn("id"));

Expected behaviour: 1
Current behaviour: 0

As far as I understand from java.sql.ResultSet javadoc, fields in ResultSet are indexed starting from 1, not 0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.