From 20a22642ee02e2b1ef7036e0eb84e48b2a7880ac Mon Sep 17 00:00:00 2001 From: Maxime Wiewiora <48218208+maximevw@users.noreply.github.com> Date: Sat, 30 Sep 2023 13:36:37 +0200 Subject: [PATCH] Prepare version 4.10.0 - Add vectors similarity functions from CEP-30 into the numeric functions listed into the DatabaseMetadata. - Allow disabling DSE tests using Maven profile. --- CHANGELOG.md | 5 +- README.md | 33 +++++-- pom.xml | 29 +++++- .../jdbc/CassandraDatabaseMetaData.java | 7 +- .../TableMetadataResultSetBuilder.java | 4 +- .../cassandra/jdbc/types/DataTypeEnum.java | 10 +- .../jdbc/DbaasAstraIntegrationTest.java | 93 ++++++++++--------- .../cassandra/jdbc/UsingDseContainerTest.java | 8 +- .../jdbc/VectorsDseContainerTest.java | 12 +-- src/test/resources/initEmbeddedDse.cql | 1 + 10 files changed, 123 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fadcdaf..28de2a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [4.10.0] - Unreleased +## [4.10.0] - 2023-09-30 ### Added - Add support for new [`vector` CQL type](https://datastax-oss.atlassian.net/browse/JAVA-3060) - defined in [CEP-30](https://cwiki.apache.org/confluence/x/OQ40Dw). + defined in [CEP-30](https://cwiki.apache.org/confluence/x/OQ40Dw) + Also see PR [#27](https://github.com/ing-bank/cassandra-jdbc-wrapper/pull/27). - Implement the method `getWarnings()` in `CassandraResultSet`. - Implement the following methods of `CassandraDatabaseMetaData`: `getBestRowIdentifier(String, String, String, int, boolean)` and `getAttributes(String, String, String, String)`. diff --git a/README.md b/README.md index b864742..3924a0a 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,17 @@ To compile and run tests, execute the following Maven command: ```bash mvn clean package ``` + +#### Some considerations about running tests + +If for some reason the tests using DataStax Enterprise server (`*DseContainerTest`) fail in your local environment, you +might disable them using the Maven profile `disableDseTests`: +```bash +mvn clean package -PdisableDseTests +``` + +The test suite also includes integration tests with AstraDB (`DbaasAstraIntegrationTest`). These tests require an +AstraDB token configured in the environment variable `ASTRA_DB_APPLICATION_TOKEN`, otherwise they are skipped. ### Integration in Maven projects @@ -265,8 +276,11 @@ For further information about custom implementations of `SslEngineFactory`, see ### Connecting to DBaaS -In order to connect to the cloud [Cassandra-based DBaaS AstraDB](https://www.datastax.com/astra) cluster, one would -need to specify: +An alternative JDBC driver based on this one exists to ease the connection to the cloud +[Cassandra-based DBaaS AstraDB](https://www.datastax.com/astra) cluster: +[Astra JDBC driver](https://github.com/DataStax-Examples/astra-jdbc-connector/tree/main). Do not hesitate to use it if you are in this specific situation. + +It's still possible to connect to AstraDB using this JDBC wrapper, so one would need to specify: * `secureconnectbundle`: the fully qualified path of the cloud secure connect bundle file * `keyspace`: the keyspace to connect to * `user`: the username @@ -352,7 +366,8 @@ CREATE TABLE example_table ( varint_col varint, string_set_col set, string_list_col list, - string_map_col map + string_map_col map, + vector_col vector ); ``` @@ -360,6 +375,7 @@ To insert a record into `example_table` using a prepared statement: ```java import com.datastax.oss.driver.api.core.data.CqlDuration; +import com.datastax.oss.driver.api.core.data.CqlVector; import java.io.ByteArrayInputStream; import java.sql.Date; @@ -370,8 +386,8 @@ public class HelloCassandra { final String insertCql = "INSERT INTO example_table (bigint_col, ascii_col, blob_col, boolean_col, decimal_col, " + "double_col, float_col, inet_col, int_col, smallint_col, text_col, timestamp_col, time_col, date_col, " + "tinyint_col, duration_col, uuid_col, timeuuid_col, varchar_col, varint_col, string_set_col, " - + "string_list_col, string_map_col) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), ?, ?, ?, ?, ?);"; + + "string_list_col, string_map_col, vector_col) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), ?, ?, ?, ?, ?, ?);"; final PreparedStatement preparedStatement = connection.prepareStatement(insertCql); preparedStatement.setObject(1, 1L); // bigint preparedStatement.setObject(2, "test"); // ascii @@ -401,14 +417,16 @@ public class HelloCassandra { sampleSet.add("test1"); sampleSet.add("test2"); preparedStatement.setObject(20, sampleSet); // set - ArrayList sampleList = new ArrayList(); + final ArrayList sampleList = new ArrayList(); sampleList.add("test1"); sampleList.add("test2"); preparedStatement.setObject(21, sampleList); // list - HashMap sampleMap = new HashMap(); + final HashMap sampleMap = new HashMap(); sampleMap.put("1", "test1"); sampleMap.put("2", "test2"); preparedStatement.setObject(22, sampleMap); // map + final CqlVector sampleVector = CqlVector.newInstance(1.0f, 0.0f, 1.0f, 0.5f, 0.2f); + preparedStatement.setObject(23, sampleVector); // vector // Execute the prepare statement. preparedStatement.execute(); } @@ -696,6 +714,7 @@ We use [SemVer](http://semver.org/) for versioning. * Madhavan Sridharan - **[@msmygit](https://github.com/msmygit)** * Marius Jokubauskas - **[@mjok](https://github.com/mjok)** * Sualeh Fatehi - **[@sualeh](https://github.com/sualeh)** +* Cedrick Lunven - **[@clun](https://github.com/clun)** And special thanks to the developer of the original project on which is based this one: * Alexander Dejanovski - **[@adejanovski](https://github.com/adejanovski)** diff --git a/pom.xml b/pom.xml index 36ee2e8..f79a208 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.ing.data cassandra-jdbc-wrapper - 4.9.1 + 4.10.0 jar Cassandra JDBC Wrapper @@ -109,10 +109,10 @@ 2.2 5.10.0 1.10.0 - 1.18.28 + 1.18.30 3.12.4 1.7.36 - 1.18.3 + 1.19.0 0.6.11 3.3.0 @@ -241,14 +241,14 @@ ${testcontainers.version} test - + com.datastax.astra astra-sdk-devops ${astra-sdk.version} test - + com.datastax.oss java-driver-query-builder @@ -461,5 +461,24 @@ + + + + disableDseTests + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + *DseContainerTest.java + + + + + + diff --git a/src/main/java/com/ing/data/cassandra/jdbc/CassandraDatabaseMetaData.java b/src/main/java/com/ing/data/cassandra/jdbc/CassandraDatabaseMetaData.java index 3ca43ca..8c7bce8 100644 --- a/src/main/java/com/ing/data/cassandra/jdbc/CassandraDatabaseMetaData.java +++ b/src/main/java/com/ing/data/cassandra/jdbc/CassandraDatabaseMetaData.java @@ -511,8 +511,9 @@ public int getMaxUserNameLength() { @Override public String getNumericFunctions() throws SQLException { checkStatementClosed(); - // Cassandra does not implement natively numeric functions. - return StringUtils.EMPTY; + // We consider here the vectors similarity functions introduced by CEP-30 as numeric functions (see + // https://issues.apache.org/jira/browse/CASSANDRA-18640). + return "similarity_cosine,similarity_euclidean,similarity_dot_product"; } @Override @@ -779,7 +780,7 @@ public String getTimeDateFunctions() throws SQLException { checkStatementClosed(); // See: https://cassandra.apache.org/doc/latest/cassandra/cql/functions.html return "dateOf,now,minTimeuuid,maxTimeuuid,unixTimestampOf,toDate,toTimestamp,toUnixTimestamp,currentTimestamp," - + "currentDate,currentTime,currentTimeUUID,"; + + "currentDate,currentTime,currentTimeUUID"; } @Override diff --git a/src/main/java/com/ing/data/cassandra/jdbc/metadata/TableMetadataResultSetBuilder.java b/src/main/java/com/ing/data/cassandra/jdbc/metadata/TableMetadataResultSetBuilder.java index b7346f4..b458deb 100644 --- a/src/main/java/com/ing/data/cassandra/jdbc/metadata/TableMetadataResultSetBuilder.java +++ b/src/main/java/com/ing/data/cassandra/jdbc/metadata/TableMetadataResultSetBuilder.java @@ -330,8 +330,8 @@ public CassandraMetadataResultSet buildPrimaryKeys(final String schema, final St *

* * @param schema A schema name pattern. It must match the schema name as it is stored in the database; {@code ""} - * retrieves those without a schema and {@code null} means that the schema name should not be used to - * narrow the search. Using {@code ""} as the same effect as {@code null} because here the schema + * retrieves those without a schema and {@code null} means that the schema name should not be used + * to narrow the search. Using {@code ""} as the same effect as {@code null} because here the schema * corresponds to the keyspace and Cassandra tables cannot be defined outside a keyspace. * @param table A table name. It must match the table name as it is stored in the database. * @param scope The scope of interest, using the same values as {@code SCOPE} in the result set. diff --git a/src/main/java/com/ing/data/cassandra/jdbc/types/DataTypeEnum.java b/src/main/java/com/ing/data/cassandra/jdbc/types/DataTypeEnum.java index a1fe3db..ff34159 100644 --- a/src/main/java/com/ing/data/cassandra/jdbc/types/DataTypeEnum.java +++ b/src/main/java/com/ing/data/cassandra/jdbc/types/DataTypeEnum.java @@ -172,6 +172,8 @@ public enum DataTypeEnum { */ VECTOR(DataType.LIST, CqlVector.class, "Vector"); + static final String VECTOR_CLASSNAME = "org.apache.cassandra.db.marshal.VectorType"; + private static final Map CQL_DATATYPE_TO_DATATYPE; /** @@ -185,8 +187,6 @@ public enum DataTypeEnum { final int protocolId; - static final String VECTOR_CLASSNAME = "org.apache.cassandra.db.marshal.VectorType"; - static { CQL_DATATYPE_TO_DATATYPE = new HashMap<>(); for (final DataTypeEnum dataType : DataTypeEnum.values()) { @@ -220,6 +220,7 @@ public static DataTypeEnum fromCqlTypeName(final String cqlTypeName) { if (cqlTypeName.startsWith(UDT.cqlType)) { return UDT; } + // Manage vector type if (cqlTypeName.contains(VECTOR_CLASSNAME)) { return VECTOR; } @@ -337,7 +338,10 @@ public String toString() { */ public static String cqlName(@Nonnull final com.datastax.oss.driver.api.core.type.DataType dataType) { final String rawCql = dataType.asCql(false, false); - return rawCql.contains(VECTOR_CLASSNAME) ? VECTOR.cqlType : rawCql; + if (rawCql.contains(VECTOR_CLASSNAME)) { + return VECTOR.cqlType; + } + return rawCql; } } diff --git a/src/test/java/com/ing/data/cassandra/jdbc/DbaasAstraIntegrationTest.java b/src/test/java/com/ing/data/cassandra/jdbc/DbaasAstraIntegrationTest.java index c674a9c..27252f0 100644 --- a/src/test/java/com/ing/data/cassandra/jdbc/DbaasAstraIntegrationTest.java +++ b/src/test/java/com/ing/data/cassandra/jdbc/DbaasAstraIntegrationTest.java @@ -33,39 +33,41 @@ import java.sql.SQLException; /** - * Test JDBC Driver against DbAAS Astra. - * To run this test define environment variable ASTRA_DB_APPLICATION_TOKEN + * Test JDBC Driver against DBaaS Astra. + * To run this test class, define an environment variable ASTRA_DB_APPLICATION_TOKEN containing the AstraDB token, * but not having any token does not block the build. */ @TestMethodOrder(org.junit.jupiter.api.MethodOrderer.OrderAnnotation.class) class DbaasAstraIntegrationTest { private static final Logger log = LoggerFactory.getLogger(DbaasAstraIntegrationTest.class); + private static final String ASTRA_DB_TOKEN_ENV_VARIABLE = "ASTRA_DB_APPLICATION_TOKEN"; + private static final String ASTRA_DB_TOKEN_PATTERN = "Astra.*"; private static final String DATABASE_NAME = "test_cassandra_jdbc"; private static final String KEYSPACE_NAME = "test"; + static CassandraConnection sqlConnection = null; @BeforeAll static void setupAstra() throws Exception { - if (System.getenv("ASTRA_DB_APPLICATION_TOKEN") != null) { - log.debug("ASTRA_DB_APPLICATION_TOKEN is provided, Astra Test is executed"); - + if (System.getenv(ASTRA_DB_TOKEN_ENV_VARIABLE) != null) { + log.debug("ASTRA_DB_APPLICATION_TOKEN is provided, AstraDB tests are executed."); /* * Devops API Client (create database, resume, delete) */ - AstraDbClient astraDbClient = new AstraDbClient(TestUtils.getAstraToken()); - log.debug("Connected the dbaas API"); + final AstraDbClient astraDbClient = new AstraDbClient(TestUtils.getAstraToken()); + log.debug("Connected the DBaaS API."); /* - * Set up a Database in Astra : create if not exist, resume if needed + * Set up a Database in Astra: create if not exist, resume if needed. * Vector Database is Cassandra DB with vector support enabled. - * It can take up to 1 min to create the database if not exists + * It can take up to 1 min to create the database if not exists. */ String dbId = TestUtils.setupVectorDatabase(DATABASE_NAME, KEYSPACE_NAME); Assertions.assertTrue(astraDbClient.findById(dbId).isPresent()); Assertions.assertEquals(DatabaseStatusType.ACTIVE, astraDbClient.findById(dbId).get().getStatus()); - log.debug("Database ready"); + log.debug("Database ready."); /* * Download cloud secure bundle to connect to the database. @@ -79,7 +81,7 @@ static void setupAstra() throws Exception { /* * Building jdbcUrl and sqlConnection. - * Note: Astra can be access with only a token (username='token') + * Note: Astra can be accessed with only a token (username='token'). */ sqlConnection = (CassandraConnection) DriverManager.getConnection( "jdbc:cassandra://dbaas/" + KEYSPACE_NAME + @@ -88,13 +90,13 @@ static void setupAstra() throws Exception { "&consistency=" + "LOCAL_QUORUM" + "&secureconnectbundle=/tmp/" + DATABASE_NAME + "_scb.zip"); } else { - log.debug("ASTRA_DB_APPLICATION_TOKEN is not defined, skipping ASTRA test"); + log.debug("ASTRA_DB_APPLICATION_TOKEN is not defined, skipping AstraDB tests."); } } @Test @Order(1) - @EnabledIfEnvironmentVariable(named = "ASTRA_DB_APPLICATION_TOKEN", matches = "Astra.*") + @EnabledIfEnvironmentVariable(named = ASTRA_DB_TOKEN_ENV_VARIABLE, matches = ASTRA_DB_TOKEN_PATTERN) void givenConnection_whenCreateTable_shouldTableExist() throws SQLException { // Given Assertions.assertNotNull(sqlConnection); @@ -107,15 +109,15 @@ void givenConnection_whenCreateTable_shouldTableExist() throws SQLException { .withColumn("lastname", DataTypes.TEXT) .build().getQuery()); // Then - Assertions.assertTrue(tableExist("simple_table")); + Assertions.assertTrue(tableExists("simple_table")); } @Test @Order(2) - @EnabledIfEnvironmentVariable(named = "ASTRA_DB_APPLICATION_TOKEN", matches = "Astra.*") + @EnabledIfEnvironmentVariable(named = ASTRA_DB_TOKEN_ENV_VARIABLE, matches = ASTRA_DB_TOKEN_PATTERN) void givenTable_whenInsert_shouldRetrieveData() throws Exception { // Given - Assertions.assertTrue(tableExist("simple_table")); + Assertions.assertTrue(tableExists("simple_table")); // When String insertSimpleCQL = "INSERT INTO simple_table (email, firstname, lastname) VALUES(?,?,?)"; final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement(insertSimpleCQL); @@ -129,52 +131,52 @@ void givenTable_whenInsert_shouldRetrieveData() throws Exception { @Test @Order(3) - @EnabledIfEnvironmentVariable(named = "ASTRA_DB_APPLICATION_TOKEN", matches = "Astra.*") + @EnabledIfEnvironmentVariable(named = ASTRA_DB_TOKEN_ENV_VARIABLE, matches = ASTRA_DB_TOKEN_PATTERN) void givenConnection_whenCreateTableVector_shouldTableExist() throws Exception { // When - sqlConnection.createStatement().execute("" + + sqlConnection.createStatement().execute( "CREATE TABLE IF NOT EXISTS pet_supply_vectors (" + " product_id TEXT PRIMARY KEY," + " product_name TEXT," + " product_vector vector)"); // Then - Assertions.assertTrue(tableExist("pet_supply_vectors")); - sqlConnection.createStatement().execute("" + + Assertions.assertTrue(tableExists("pet_supply_vectors")); + sqlConnection.createStatement().execute( "CREATE CUSTOM INDEX IF NOT EXISTS idx_vector " + "ON pet_supply_vectors(product_vector) " + "USING 'StorageAttachedIndex'"); // When - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pf1843','HealthyFresh - Chicken raw dog food',[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])"); - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pf1844','HealthyFresh - Beef raw dog food',[1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])"); - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pt0021','Dog Tennis Ball Toy',[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0])"); - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pt0041','Dog Ring Chew Toy',[0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])"); - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pf7043','PupperSausage Bacon dog Treats',[0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1])"); - sqlConnection.createStatement().execute("" + - "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + - "VALUES ('pf7044','PupperSausage Beef dog Treats',[0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pf1843','HealthyFresh - Chicken raw dog food',[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pf1844','HealthyFresh - Beef raw dog food',[1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pt0021','Dog Tennis Ball Toy',[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pt0041','Dog Ring Chew Toy',[0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pf7043','PupperSausage Bacon dog Treats',[0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1])"); + sqlConnection.createStatement().execute( + "INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) " + + "VALUES ('pf7044','PupperSausage Beef dog Treats',[0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0])"); // Then (warning on Cassandra expected) Assertions.assertEquals(6, countRecords("pet_supply_vectors")); } @Test @Order(4) - @EnabledIfEnvironmentVariable(named = "ASTRA_DB_APPLICATION_TOKEN", matches = "Astra.*") + @EnabledIfEnvironmentVariable(named = ASTRA_DB_TOKEN_ENV_VARIABLE, matches = ASTRA_DB_TOKEN_PATTERN) void givenVectorTable_whenSimilaritySearch_shouldReturnResults() throws Exception { // Given - Assertions.assertTrue(tableExist("pet_supply_vectors")); + Assertions.assertTrue(tableExists("pet_supply_vectors")); Assertions.assertEquals(6, countRecords("pet_supply_vectors")); // When - final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement("" + + final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement( "SELECT\n" + " product_id, product_vector,\n" + " similarity_dot_product(product_vector,[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]) as similarity\n" + @@ -190,16 +192,17 @@ void givenVectorTable_whenSimilaritySearch_shouldReturnResults() throws Exceptio Assertions.assertEquals(3.0d, rs.getDouble("similarity")); } - private boolean tableExist(String tableName) throws SQLException { - String existTableCql = "select table_name,keyspace_name from system_schema.tables where keyspace_name=? and table_name=?"; + private boolean tableExists(final String tableName) throws SQLException { + final String existTableCql = + "select table_name,keyspace_name from system_schema.tables where keyspace_name=? and table_name=?"; final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement(existTableCql); prepStatement.setString(1, KEYSPACE_NAME); prepStatement.setString(2, tableName); return prepStatement.executeQuery().next(); } - private int countRecords(String tablename) throws SQLException { - String countRecordsCql = "select count(*) from " + tablename; + private int countRecords(final String tableName) throws SQLException { + String countRecordsCql = "select count(*) from " + tableName; final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement(countRecordsCql); final ResultSet resultSet = prepStatement.executeQuery(); resultSet.next(); diff --git a/src/test/java/com/ing/data/cassandra/jdbc/UsingDseContainerTest.java b/src/test/java/com/ing/data/cassandra/jdbc/UsingDseContainerTest.java index 1a34631..b1705ab 100644 --- a/src/test/java/com/ing/data/cassandra/jdbc/UsingDseContainerTest.java +++ b/src/test/java/com/ing/data/cassandra/jdbc/UsingDseContainerTest.java @@ -32,11 +32,11 @@ abstract class UsingDseContainerTest { // https://www.testcontainers.org/test_framework_integration/manual_lifecycle_control/#singleton-containers static CassandraContainer cassandraContainer; - protected static void initializeContainer(String version) { - DockerImageName dockerImageName = DockerImageName - .parse("datastax/dse-server:"+ version) + protected static void initializeContainer() { + // For the official DataStax Enterprise server image, see here: https://hub.docker.com/r/datastax/dse-server/ + final DockerImageName dseServerImage = DockerImageName.parse("datastax/dse-server:7.0.0-a") .asCompatibleSubstituteFor("cassandra"); - cassandraContainer = new CassandraContainer<>(dockerImageName) + cassandraContainer = new CassandraContainer<>(dseServerImage) .withEnv("DS_LICENSE", "accept") .withEnv("CLUSTER_NAME", "embedded_test_cluster") .withEnv("DC", "datacenter1") diff --git a/src/test/java/com/ing/data/cassandra/jdbc/VectorsDseContainerTest.java b/src/test/java/com/ing/data/cassandra/jdbc/VectorsDseContainerTest.java index a123924..6bc816c 100644 --- a/src/test/java/com/ing/data/cassandra/jdbc/VectorsDseContainerTest.java +++ b/src/test/java/com/ing/data/cassandra/jdbc/VectorsDseContainerTest.java @@ -17,27 +17,23 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** - * Test CQL Vector data type + * Test CQL Vector data type using DataStax Enterprise. */ class VectorsDseContainerTest extends UsingDseContainerTest { private static final String KEYSPACE = "test_keyspace_vect"; @BeforeAll - static void setup() throws Exception { - initializeContainer("7.0.0-a"); + static void finalizeSetUpTests() throws Exception { + initializeContainer(); initConnection(KEYSPACE, "version=3.0.0", "localdatacenter=datacenter1"); } @Test void givenVectorTable_whenSimilaritySearch_shouldReturnResults() throws Exception { // When - final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement("" + + final CassandraPreparedStatement prepStatement = sqlConnection.prepareStatement( "SELECT\n" + " product_id, product_vector,\n" + " similarity_dot_product(product_vector,[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]) as similarity\n" + diff --git a/src/test/resources/initEmbeddedDse.cql b/src/test/resources/initEmbeddedDse.cql index c5b41cd..8568e6e 100644 --- a/src/test/resources/initEmbeddedDse.cql +++ b/src/test/resources/initEmbeddedDse.cql @@ -20,6 +20,7 @@ VALUES ('pf1843','HealthyFresh - Chicken raw dog food',[1, 1, 1, 1, 1, 0, 0, 0, INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) VALUES ('pf1844','HealthyFresh - Beef raw dog food',[1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]); + INSERT INTO pet_supply_vectors (product_id, product_name, product_vector) VALUES ('pt0021','Dog Tennis Ball Toy',[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0]);