Vert.x Cassandra Client i DataStax Astra
DataStax Astra to dystrybucja bazy danych NoSQL Apache Cassandra™ oparta na modelu DBaaS (Database as a Service). Obudowana w dodatkowy interfejs GraphQL oraz API REST-owe jest bardzo ciekawym produktem, który warto wziąć pod uwagę podczas wyboru bazy danych do aplikacji. Od maja 2020 możemy wypróbować takie rozwiązanie za darmo (10 GB w chmurze Google).
Jeśli aplikację chcemy zbudować w oparciu o Vert.x, to możemy do tego wykorzystać moduł io.vertx:vertx-cassandra-client. Z jednej strony, moduł ten wykorzystuje sterowniki firmy DataStax, z drugiej jednak wersja zależności jest dosyć wiekowa i możemy mieć trudności w ustawieniu połączenia z bazą. Jeśli nie interesuje nas połączenie za pomocą sterowników, nie ma przeszkód żebyśmy skorzystali z komunikacji HTTP.
Połączenie z bazą
Po utworzeniu bazy i przejściu do strony opisującej sposoby połączenia, dostajemy możliwość pobrania paczki potrzebnej do bezpiecznego połączenia z bazą. W paczce znajdują się certyfikaty TLS oraz namiary na naszą bazę. W dokumentacji szybko odnajdziemy przykładowy kod potrzebny do ustanowienia takiego połączenia.
Obecna wersja vertx-cassandra-client (3.9.x) używa sterowników DataStax com.datastax.cassandra:cassandra-driver-core w wersji 3.5.0. Niestety, opisana w dokumentacji metoda konfigurująca połączenie z bazą (withCloudSecureConnectBundle) z pliku dostarczonego przez DataStax została dodana dopiero w wersji 3.8.0. Musimy podbić wersję sterownika, gdyż nowsza wersja Vert.x'a 4.0 (beta) nie rozwiązuje jeszcze tego problemu.
Vert.x | Wesja sterownika w Vert.x | withCloudSecureConnectBundle |
---|---|---|
io.vertx:vertx-cassandra-client:3.9.3 | com.datastax.cassandra:cassandra-driver-core:3.5.0 | com.datastax.cassandra:cassandra-driver-core:3.8.0+ |
io.vertx:vertx-cassandra-client:4.0.0-milestone5 | com.datastax.oss:java-driver-core:4.2.2 | com.datastax.oss:java-driver-core:4.3.0+ |
Konfiguracja zależności
W przypadku wersji Vert.x oprócz podbicia wersji minor sterownika 3.x, konieczne będzie dodatkowo obniżenie wersji modułu guava z 25.1-jre (wykorzystywany przez Vert.x) do 19.0 (wykorzystywany przez sterownik). W ten sposób unikniemy poniższego błędu:
java.lang.NoSuchMethodError: 'java.lang.String com.google.common.net.HostAndPort.getHostText()'
at com.datastax.driver.core.CloudConfigFactory.getSniProxyAddress(CloudConfigFactory.java:232)
at com.datastax.driver.core.CloudConfigFactory.createCloudConfig(CloudConfigFactory.java:119)
at com.datastax.driver.core.Cluster$Builder.withCloudSecureConnectBundle(Cluster.java:1456)
W przypadku Gradle zrobimy to za pomocą prostej konfiguracji zależności aplikacji w standardowym pliku build.gradle
:
dependencies {
// ...
implementation('io.vertx:vertx-cassandra-client:3.9.3') {
exclude group: 'com.google.guava', module: 'guava'
}
implementation group: 'com.google.guava', name: 'guava', version: '19.0'
implementation 'com.datastax.cassandra:cassandra-driver-core:3.10.2'
// ...
}
Dla pliku pom.xml
Mavena będzie to wyglądało mniej więcej tak:
<project>
<!-- ... -->
<dependencies>
<!-- ... -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-cassandra-client</artifactId>
<version>3.9.3</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.10.2</version>
<scope>compile</scope>
</dependency>
<!-- ... -->
</dependencies>
<!-- ... -->
</project>
Kod
Generalnie taka konfiguracja powinna wystarczyć do ustanowienia połączenia w wersji 3.x (Vert.x/sterownik). Po umieszczeniu paczki konfiguracyjnej w folderze resources oraz ustawieniu loginu i hasła będziemy w stanie utworzyć klienta, za pomocą którego wywołamy zapytania na bazie Astra:
CassandraClientOptions options = new CassandraClientOptions(Cluster.builder()
.withCloudSecureConnectBundle(Thread.currentThread().getContextClassLoader().getResourceAsStream("secure-connect-<db_name>.zip"))
.withAuthProvider(new PlainTextAuthProvider(config.getString("cassandra.login"), config.getString("cassandra.password"))));
CassandraClient client = CassandraClient.create(vertx, options);
W celu sprawdzenia połączenia możemy wywołać proste zapytanie:
client.execute("SELECT now() FROM system.local;", res -> {
if (res.failed()) {
logger.error("NOK", res.cause());
} else {
logger.info("OK " + res.result());
}
});
Podobny zabieg (konfiguracyjny), prawdopodobnie już bez wykluczania Guavy wymagany będzie również w przypadku obecnej wersji 4.x. Zakładając oczywiście, że interfejs najnowszego sterownika 4.3+ jest kompatybilny wstecz ze sterownikiem 4.2.2 wykorzystywanym przez Vert.x w wersji beta (kamień milowy 5). Osobiście jeszcze tego nie testowałem, ale zachęcam do wypróbowania i podzielenia się wynikami.