The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Cassandra クライアントの使用

Apache Cassandra®は、フリーでオープンソースの分散型ワイドカラムストアのNoSQLデータベース管理システムで、多くのコモディティサーバーにまたがる大量のデータを処理するように設計されており、単一障害点のない高可用性を提供します。

このガイドでは、RESTサービスでCassandraデータベースを使用する方法を見ていきます。

このエクステンションはサードパーティによって開発されたもので、Quarkus Platformの一部です。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • 稼働中の Apache CassandraDataStax Enterprise(DSE)、または DataStax Astraデータベース、あるいはきれいなDockerのインストール

アーキテクチャ

このクイックスタート・ガイドでは、 DataStax Javaドライバーを使用してApache Cassandra、DataStax Enterprise(DSE)、またはDataStax Astraデータベースに接続できる Cassandra Quarkusエクステンションを使用してRESTアプリケーションを構築する方法を説明します。

このガイドでは、DataStax Object Mapper も使用します。これは、Java から CQL にマッピングする強力なフレームワークで、CQLクエリーを手動で記述する手間を省くことで、アプリケーションのデータアクセス階層コードを大幅に簡素化します。

このガイドで構築されたアプリケーションは非常にシンプルです: ユーザーはフォームを使用してリストに要素を追加することができ、アイテムリストが更新されます。ブラウザーとサーバー間の情報はすべてJSONフォーマットで、各要素はCassandraデータベースに保存されます。

ソリューション

次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

ソリューションはCassandra QuarkusエクステンションGitHubレポジトリの クイックスタートディレクトリ にあります。

空白の Maven プロジェクトの作成

まず、新しいMavenプロジェクトを作成し、 quickstart ディレクトリーに存在する pom.xml ファイルをコピーします。

pom.xml 、必要なQuarkusのエクステンションや依存関係をすべてインポートしています。

データモデルとデータアクセスオブジェクトの作成

この例では、果物のリストを管理するアプリケーションを作成します。

まず、以下のように Fruit クラスであらわされるデータモデルを作成してみましょう。

@Entity
@PropertyStrategy(mutable = false)
public class Fruit {

    @PartitionKey
    private final String name;

    private final String description;

    public Fruit(String name, String description) {
      this.name = name;
      this.description = description;
    }
  // getters, hashCode, equals, toString methods omitted for brevity
}

前述のとおり、ここではDataStax Object Mapperを使用しています。つまり、CQLクエリーを手動で記述するのではなく、データ・モデルにいくつかのアノテーションを付け、裏側でマッパーが適切なCQLクエリーを生成するのです。

これが、 Fruit クラスが @Entity でアノテーションされている理由です。このアノテーションは、Cassandraテーブルにマッピングされる エンティティ・クラス としてマークされます。このクラスのインスタンスは、Cassandraデータベースに自動的に永続化され、そこから取得されます。ここでは、テーブル名はクラス名から推測されます: fruit

また、name フィールドは Cassandra パーティションキーを表すため、ObjectMapper ライブラリーの別のアノテーションである @PartitionKey のアノテーションを付けています。

エンティティークラスには通常、今回のように @PropertyStrategy(mutable = false) のアノテーションが付けられている場合を除き、デフォルトの引数なしのコンストラクタが必要です。

次のステップでは、 Fruit エンティティーのインスタンスを管理する DAO (データアクセスオブジェクト) インターフェイスを作成します。

@Dao
public interface FruitDao {
  @Update
  void update(Fruit fruit);

  @Select
  PagingIterable<Fruit> findAll();
}

このインターフェイスは、REST サービスで使用される操作を公開します。繰り返しになりますが、アノテーション @Dao は DataStaxObjectMapper から取得され、このインターフェイスの実装も自動的に生成されます。

findAll メソッドの特別なリターンタイプにも注意してください PagingIterable: これはドライバーによって返される結果セットの基本タイプです。

Finally, let’s create the Mapper interface:

@Mapper
public interface FruitMapper {
  @DaoFactory
  FruitDao fruitDao();
}

@Mapper アノテーションは、DataStaxObjectMapper によって認識されるさらに別のアノテーションです。マッパーは DAO のインスタンスを構築します。この場合に、アウトマッパーは唯一の DAO である FruitDao のインスタンスを構築しています。

サービスと JSONREST エンドポイントの作成

ここで、アプリケーションのビジネス層となる FruitService を作成し、Cassandraデータベースから果物をセーブ/ロードします。

@ApplicationScoped
public class FruitService {

  @Inject FruitDao dao;

  public void save(Fruit fruit) {
    dao.update(fruit);
  }

  public List<Fruit> getAll() {
    return dao.findAll().all();
  }
}

サービスがどのように FruitDao インスタンスに注入されているかに注意してください。この DAO インスタンスは自動的に注入されます。

Cassandra Quarkus エクステンションを使用すると、次の Bean のいずれかを独自のコンポーネントに挿入できます。

  • プロジェクト内にある @Mapper アノテーション付きインターフェイスすべて。

  • プロジェクト内のすべての @Dao アノテーション付きインターフェイス。ただし、このインターフェイスは、プロジェクトのマッパーインターフェイスで宣言されており、対応する @DaoFactory アノテーション付きメソッドによって生成されている場合に限ります。

  • QuarkusCqlSession bean: このアプリケーションスコープのシングルトン Bean は、Cassandra クライアントへの主要なエントリーポイントです。これは、Quarkus 用に特別に調整されたメソッドを備えた特殊な Cassandra ドライバーセッションインスタンスです。javadoc をしっかり確認してください。

この例では、 FruitMapperFruitDao の両方をどこにでも注入できますが、 FruitServiceFruitDao を注入しています。

最後に必要なのは、GETとPOSTのメソッドを公開するREST APIです。

@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

  @Inject FruitService fruitService;

  @GET
  public List<FruitDto> getAll() {
    return fruitService.getAll().stream().map(this::convertToDto).collect(Collectors.toList());
  }

  @POST
  public void add(FruitDto fruit) {
    fruitService.save(convertFromDto(fruit));
  }

  private FruitDto convertToDto(Fruit fruit) {
    return new FruitDto(fruit.getName(), fruit.getDescription());
  }

  private Fruit convertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription());
  }
}

FruitResourceFruitService インスタンスを自動的に注入していることに注目してください。

通常、REST API とデータアクセス層の間で同じエンティティーオブジェクトを使用することはお勧めしません。各 API を互いに独立して進化させるには、これらのレイヤーを実際に分離し、個別の API を使用する必要があります。このように、異なるオブジェクトを ( FruitDto ) を使用する理由です。DTO という用語は、「Data Transfer Object」の略です。この DTO オブジェクトは、HTTP メッセージで JSON に対する変換を自動的に行います。

public class FruitDto {

  private String name;
  private String description;

  public FruitDto() {}

  public FruitDto(String name, String description) {
    this.name = name;
    this.description = description;
  }
  // getters and setters omitted for brevity
}

JSON との間の変換は、このガイドの pom.xml ファイルに含まれている Quarkus RESTEasy Reactive エクステンションによって自動的に行われます。アプリケーションに手動で追加する場合は、以下のスニペットをアプリケーションの ppm.xml ファイルに追加します。

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
JSONのシリアライゼーションレイヤーで使用されるDTOクラスは、デフォルトの引数なしのコンストラクタが必要です。

DTO から JSON への変換は自動的に処理されますが、それでも Fruit から FruitDto に、またはその逆に変換する必要があります。これは手動で行う必要があるので、 FruitResource で 2 つの変換メソッド convertToDtoconvertFromDto を宣言しています。

この例では、 FruitFruitDto は非常に似ているので、すべてに Fruit を使用しないのはなぜかと思うかもしれませんが、実際には、DTO とエンティティーの構造が大きく異なることは珍しくありません。

Cassandra データベースへの接続

ApacheCassandra または DataStaxEnterprise (DSE) への接続

構成する主なプロパティーは次のとおりです。Cassandraデータベースにアクセスするための contact-points 、ドライバーによって必要とされる local-datacenter そしてオプションでバインド先のキースペースです。

設定のサンプルは以下のようになります。

quarkus.cassandra.contact-points={cassandra_ip}:9042
quarkus.cassandra.local-datacenter={dc_name}
quarkus.cassandra.keyspace={keyspace}

この例では、localhost上で動作する単一のインスタンスを使用しており、データを含むキースペースは k1 となっています。

quarkus.cassandra.contact-points=127.0.0.1:9042
quarkus.cassandra.local-datacenter=datacenter1
quarkus.cassandra.keyspace=k1

クラスタがプレーンテキスト認証を必要とする場合は、さらに2つの設定を行う必要があります。 usernamepassword です。

quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t

DataStaxAstra クラウドデータベースへの接続

DataStax Astra に接続する場合には、接続先とデータセンターを提供する代わりに、いわゆる セキュア接続バンドル を提供して、Astra のセキュア接続バンドルファイルへの有効なパスを指定する必要があります。セキュア接続バンドルは、AstraWeb コンソールからダウンロードできます。

Astra クラスターでは常に認証が必要なため、ユーザー名とパスワードも指定する必要があります。

DataStax Astraのサンプル構成は次のようになります。

quarkus.cassandra.cloud.secure-connect-bundle=/path/to/secure-connect-bundle.zip
quarkus.cassandra.auth.username=john
quarkus.cassandra.auth.password=s3cr3t
quarkus.cassandra.keyspace=k1

高度なドライバー設定

application.conf または application.json ファイルを使用して、他の Java ドライバーの設定を設定することができます。これらのファイルは、アプリケーションのクラスパスに配置する必要があります。すべての設定は、基礎となるドライバー設定メカニズムに自動的に渡されます。 application.propertiesquarkus.cassandra のプレフィックスを付けて定義された設定は、 application.conf または application.json で定義された設定よりも優先されます。

設定の全リストを見るには、 ドライバーの設定リファレンス を参照してください。

ローカル Cassandra データベースの実行

デフォルトでは、Cassandra クライアントは、ポート 9042(デフォルトの Cassandra ポート)でローカル Cassandra データベースにアクセスするように構成されています。

設定 quarkus.cassandra.local-datacenter が、Cassandraクラスターのデータセンターと一致していることを確認してください。
ローカルのデータセンターの名前がわからない場合は、以下の CQL クエリを実行することでこの値を見つけることができます : SELECT data_center FROM system.local

Docker を使用して Cassandra データベースを実行する場合は、次のコマンドを使用してバックグラウンドでデータベースを起動できます。

docker run --name local-cassandra-instance -p 9042:9042 -d cassandra

次に、アプリケーションで使用するキースペースとテーブルを作成する必要があります。Dockerを使用している場合は、以下のコマンドを実行します。

docker exec -it local-cassandra-instance cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}"
docker exec -it local-cassandra-instance cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(name text PRIMARY KEY, description text)"

CQLSH ユーティリティーを使用して、データベースに対話式に問い合わせることもできます。

docker exec -it local-cassandra-instance cqlsh

REST API のテスト

プロジェクトのルートディレクトリー:

  • mvn clean package を実行してから、 java -jar./target/cassandra-quarkus-quickstart-*-runner.jar を実行してアプリケーションを起動します。

  • または、mvn clean quarkus:dev でアプリケーションを開発モードで実行します。

これで、curl コマンドを使用して、基盤となる REST API と対話できます。

fruit を作成するには以下を実行します。

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"name":"apple","description":"red and tasty"}' \
  http://localhost:8080/fruits

Fruit を回収するには以下を実行します。

curl -X GET http://localhost:8080/fruits

フロントエンドの作成

それでは、 FruitResource と対話するためのシンプルなウェブページを追加してみましょう。

Quarkus は、 META-INF/resources ディレクトリーの下にある静的リソースを自動的に提供します。 src/main/resources/META-INF/resources ディレクトリーに、このファイル の内容を含めて fruits.html ファイルを追加します。

これで、REST サービスと対話できるようになりました。

  • まだの場合は、 mvn clean quarkus:dev を使用してアプリケーションを起動します。

  • ブラウザーで http://localhost:8080/fruits.html を指定します。

  • フォームを使って新しいフルーツをリストに追加します。

Cassandra クライアントを使用したリアクティブプログラミング

QuarkusCqlSession インタフェース を使用すると、Quarkus およびそのリアクティブフレームワークである Mutiny をシームレスに統合する一連のリアクティブメソッドにアクセスできます。

Mutinyに慣れていない方は、 Mutiny - 直感的なリアクティブプログラミングライブラリをご覧ください。

Mutiny でリアクティブプログラミングを使用してアプリケーションを書き換えてみましょう。

First, let’s declare another DAO interface that works in a reactive way:

@Dao
public interface ReactiveFruitDao {

  @Update
  Uni<Void> updateAsync(Fruit fruit);

  @Select
  MutinyMappedReactiveResultSet<Fruit> findAll();
}

MutinyMappedReactiveResultSet の使い方に注意してください。これは、ドライバが返すオリジナルの Publisher から変換された特殊な Mutiny 型で、クエリの実行情報を取得するなど、いくつかの追加メソッドも公開されています。このインターフェイスで何も必要としない場合は、単純に Multi を返すようにメソッドを宣言することもできます: Multi<Fruit> findAll()

同様に、メソッド updateAsyncUni を返します。これは、ドライバーが返す元の結果セットから自動的に変換されます。

Cassandraドライバは、リアクティブコールにReactive Streamsの Publisher APIを使用しています。しかし、QuarkusフレームワークではMutinyを使用しています。そのため、 CqlQuarkusSession インターフェイスは、ドライバが返す Publisher インスタンスを透過的にリアクティブ型の Multi に変換します。 CqlQuarkusSessionPublisherUni に変換することもできます - この場合、パブリッシャーは最大で1行を出力し、その後完了することが期待されます。これは書き込みクエリ(行を返さない)や、最大で1行を返すことが 保証されている読み込みクエリ(例えばカウントクエリ)に適しています。

次に、 FruitMapper を適応させて、 ReactiveFruitDao インスタンスを構築する必要があります。

@Mapper
public interface FruitMapper {
  // the existing method omitted

  @DaoFactory
  ReactiveFruitDao reactiveFruitDao();
}

これで、リアクティブ DAO を活用する ReactiveFruitService を作成できます。

@ApplicationScoped
public class ReactiveFruitService {

  @Inject ReactiveFruitDao fruitDao;

  public Uni<Void> add(Fruit fruit) {
    return fruitDao.update(fruit);
  }

  public Multi<Fruit> getAll() {
    return fruitDao.findAll();
  }
}

最後に、 ReactiveFruitResource を作成できます。

@Path("/reactive-fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ReactiveFruitResource {

  @Inject ReactiveFruitService service;

  @GET
  public Multi<FruitDto> getAll() {
    return service.getAll().map(this::convertToDto);
  }

  @POST
  public Uni<Void> add(FruitDto fruitDto) {
    return service.add(convertFromDto(fruitDto));
  }

  private FruitDto convertToDto(Fruit fruit) {
    return new FruitDto(fruit.getName(), fruit.getDescription());
  }

  private Fruit convertFromDto(FruitDto fruitDto) {
    return new Fruit(fruitDto.getName(), fruitDto.getDescription());
  }
}

上記のリソースは、新しいエンドポイント reactive-fruits を公開しています。その機能は、以前に FruitResource で作成したものと同じですが、すべてがブロッキング操作なしでリアクティブな方法で処理されます。

上記の getAll () メソッドは Multi を返し、 add () メソッドは Uni を返します。これらのタイプは、以前使用した Mutiny タイプと同じで、Quarkus リアクティブ REST API により自動的に認識されるので、JSON に変換する必要はありません。

RESTEasy Reactive は、 UniMulti などの Mutiny リアクティブタイプをネイティブにサポートします。

この依存関係は、本書の pom.xml にすでに含まれていますが、新しいプロジェクトを最初から開始する場合は必ず追加するようにしてください。

リアクティブ REST API のテスト

上で説明したようにアプリケーションを開発モードで実行すると、curl コマンドを使用して基盤となる REST API と対話できます。

リアクティブ REST エンドポイントを使用して fruit を作成するには以下を実行します。

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"name":"banana","description":"yellow and sweet"}' \
  http://localhost:8080/reactive-fruits

リアクティブ REST エンドポイントを使用して fruit を取得するには以下を実行します。

curl -X GET http://localhost:8080/reactive-fruits

リアクティブなフロントエンドの作成

次に、 ReactiveFruitResource と対話するための簡単な Web ページを追加しましょう。 src/main/resources/META-INF/resources ディレクトリーに、 このファイル の内容を含めて reactive-fruits.html ファイルを追加します。

これで、リアクティブな REST サービスと対話できるようになりました。

  • まだの場合は、 mvn clean quarkus:dev を使用してアプリケーションを起動します。

  • ブラウザーで http://localhost:8080/reactive-fruits.html を指定します。

  • フォームを使って新しいフルーツをリストに追加します。

ヘルスチェック

Quarkus SmallRye Health エクステンションを使用している場合には、Cassandra クライアントは、Cassandra クラスターへの接続を検証するための準備ヘルスチェックを自動的に追加します。このエクステンションは、本書の pom.xml にすでに含まれていますが、アプリケーションに手動で含める必要がある場合は、次を追加してください。

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-smallrye-health</artifactId>
</dependency>

ヘルスチェックが利用可能になると、アプリケーションの /health/ready エンドポイントにアクセスして、接続検証ステータスに関する情報を取得できます。

mvn clean quarkus:dev を使用して開発モードで実行している場合には、ブラウザーで http://localhost:8080/health/ready を指定すると、次のような出力が表示されます。

{
    "status": "UP",
    "checks": [
        {
            "name": "DataStax Apache Cassandra Driver health check",
            "status": "UP",
            "data": {
                "cqlVersion": "3.4.4",
                "releaseVersion": "3.11.7",
                "clusterName": "Test Cluster",
                "datacenter": "datacenter1",
                "numberOfNodes": 1
            }
        }
    ]
}
アプリケーションでヘルスチェックをグローバルに有効にする必要があるが、Cassandra ヘルスチェックは有効にしない場合は、 application.propertiesquarkus.cassandra.health.enabled プロパティーを false に設定して Cassandra ヘルスチェックを無効にできます。

メトリクス

Cassandra Quarkus クライアントは、Cassandra セッションおよび個々の Cassandra ノードに関するメトリクスを提供できます。このクライアントは、Micrometer と MicroProfile の両方をサポートします。

メトリクスの有効化の最初のステップは、使用する予定のメトリクスフレームワークに応じて、いくつかの依存関係を追加することです。

Micrometer でのメトリクスの有効化

Micrometer は、Quarkus アプリケーションで推奨されるメトリクスフレームワークです。

アプリケーションで Micrometer メトリクスを有効にするには、pom.xml に以下を追加する必要があります。

<dependency>
  <groupId>com.datastax.oss</groupId>
  <artifactId>java-driver-metrics-micrometer</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>

このガイドでは Micrometer を使用しているため、上記の依存関係はこのガイドの pom.xml にすでに含まれています。

MicroProfile メトリクスを使用したメトリクスの有効化

pom.xml から Micrometer への依存関係を削除し、代わりに次の依存関係を追加します。

<dependency>
  <groupId>com.datastax.oss</groupId>
  <artifactId>java-driver-metrics-microprofile</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-smallrye-metrics</artifactId>
</dependency>

Cassandra メトリクスの有効化

Even when metrics are enabled in your application, the Cassandra client will not report any metrics, unless you opt in for this feature. So your next step is to enable Cassandra metrics in your application.properties file.

quarkus.cassandra.metrics.enabled=true

以上です!

最後の手順 (任意) で、Cassandra クライアントに追跡させる特定の Cassandra メトリクスをカスタマイズします。複数のメトリクスを追跡できますが、この手順をスキップすると、有用なメトリクスのデフォルトセットが自動的に追跡されます。

使用可能なメトリクス名の完全なリストについては、 Driver Setting Reference ページを参照してください。このページで advanced.metrics セクションを検索してください。また、Cassandra ドライバーのメトリクスについては、 ドライバーマニュアル で詳しく説明されています。

追跡するメトリクスをカスタマイズする場合は、次のプロパティーを使用する必要があります。

  • quarkus.cassandra.metrics.session.enabled には、有効にするセッションレベルのメトリクス (セッションに対してグローバルなメトリクス) が含まれている必要があります。

  • quarkus.cassandra.metrics.node.enabled には、有効にするノードレベルのメトリクス (Cassandra クライアントが接続する各ノードが独自のメトリクス値を取得するメトリクス) が含まれている必要があります 。

どちらのプロパティーにも、有効なメトリクス名をコンマ区切りにした一覧を使用できます。

たとえば、次の 3 つの Cassandra メトリクスを有効にする場合には、以下のとおりです。

  • セッションレベル: session.connected-nodes および session.bytes-sent;

  • ノードレベル: node.pool.open-connections

次に、application.properties に以下の設定を追加する必要があります。

quarkus.cassandra.metrics.enabled=true
quarkus.cassandra.metrics.session.enabled=connected-nodes,bytes-sent
quarkus.cassandra.metrics.node.enabled=pool.open-connections

本書の application.properties ファイルでは、すでに多くのメトリクスが有効になっています。このメトリクスリストを開始点として使用して、アプリケーションの有用な Cassandra メトリクスを公開すると適切です。

メトリクスが適切に有効になっている場合には、有効になっているすべてのメトリクスのメトリクスレポートは、アプリケーションの /metrics REST エンドポイントで利用できます。

mvn clean quarkus:dev を使用して開発モードで実行している場合には、ブラウザーで http://localhost:8080/metrics を指定するとメトリクスのリストが表示されます。名前に cassandra が含まれているメトリクスを検索します。

Cassandra メトリクスを表示するには、Cassandra クライアントを初期化して接続する必要があります。遅延初期化 (以下を参照) を使用している場合には、アプリケーションが、実際に接続してデータベースに初めてアクセスするまで、Cassandra メトリクスは表示されません。

ネイティブモードでの実行

GraalVM をインストールした場合は、以下を使用して、 ネイティブイメージのビルド が可能です。

mvn clean package -Dnative

ネイティブコンパイルにはかなりの時間がかかる可能性があることに注意してください。コンパイルが完了したら、次のようにネイティブ実行可能ファイルを実行できます。

./target/cassandra-quarkus-quickstart-*-runner

その後、ブラウザで http://localhost:8080/fruits.html を開いてアプリケーションを使用します。

Eager (先行) vs Lazy (遅延) 初期化

このエクステンションでは、どちらかを注入することができます。

  • QuarkusCqlSession Bean;

  • この Bean ( CompletionStage<QuarkusCqlSession> ) の非同期バージョン;

  • またはこの Bean のリアクティブバージョン (Uni<QuarkusCqlSession>)。

最も簡単なアプローチは、明らかに QuarkusCqlSession を直接注入することです。これは、ほとんどのアプリケーションで問題なく機能するはずですが、QuarkusCqlSession Bean を使用する前に初期化する必要があるため、このプロセスはブロックされています。

幸いにも、初期化のタイミングを制御できます。 quarkus.cassandra.init.eager-init パラメーターは、 QuarkusCqlSession bean を最初にアクセスしたタイミング (lazy) または、アプリケーションが起動するタイミング (eager) のいずれで初期化するべきかを判断します。このパラメーターのデフォルト値は、 false で、init プロセスが遅延設定されていることを意味しています。たとえば、Cassandra データベースと対話する必要がある最初の REST 要求がある場合に、 QuarkusCqlSession bean は、遅延して、最初にアクセスしたタイミングで初期化されます。

遅延初期化を使用すると、アプリケーションの起動時間が短縮され、Cassandra データベースが利用できない場合に起動が失敗しないようになります。ただし、完全に非同期のコードを使用している場合には、リスクが発生する可能性があります。たとえば、 reactive routes を使用する場合には、Vert.x イベントループスレッドなど、ブロックされるべきでないスレッドで遅延初期化が誤って発生してしまう可能性があります。そのため、このようなコンテキストでは quarkus.cassandra.init.eager-initfalse に設定して QuarkusCqlSession の挿入は避けるべきです。

Vert.x (またはその他のリアクティブフレームワーク) を使用して遅延初期化の動作を維持する場合は、代わりに CompletionStage<QuarkusCqlSession> または Uni<QuarkusCqlSession> だけを挿入してください。これらの Bean を注入すると、初期化プロセスは遅延してトリガーされますが、Vert.x イベントループを利用して、ブロックされない方法でバックグラウンドで実行されます。このようにして、Vert.x スレッドをブロックするリスクを回避できます。

または、quarkus.cassandra.init.eager-init を true に設定することもできます。この場合には、セッション Bean は、アプリケーションの起動時に、Quarkus メインスレッドで先行して初期化されます。これにより、Vert.x スレッドをブロックするリスクがなくなりますが、起動時間が (はるかに) 長くなります。

まとめ

クライアント・アプリケーションからのCassandraデータベースへのアクセスは、QuarkusとCassandraエクステンションで簡単に行えます。