Infinispanクライアントの使用
このガイドでは、Infinispan Clientエクステンションを使用して、QuarkusアプリケーションをInfinispanサーバーに接続する方法について説明します。
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOME
が適切に設定されていること -
Apache Maven 3.9.8
-
使用したい場合は、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
-
Dockerが稼働している環境
アーキテクチャ
本ガイドでは、 Infinispan RemoteCache API と getAsync
、 putAsync
の操作を利用して、挨拶のメッセージを作成、表示するGreeting Rest APIを公開します。
Quarkus Infinispan Clientエクステンションを使用して、Infinispanに接続し、対話します。
ソリューション
次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。
Gitリポジトリをクローンする: git clone https://github.com/quarkusio/quarkus-quickstarts.git
または アーカイブ をダウンロードします。
ソリューションは infinispan-client-quickstart
ディレクトリ にあります。
Maven プロジェクトの作成
まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します。
Windowsユーザーの場合:
-
cmdを使用する場合、(バックスラッシュ
\
を使用せず、すべてを同じ行に書かないでください)。 -
Powershellを使用する場合は、
-D
パラメータを二重引用符で囲んでください。例:"-DprojectArtifactId=infinispan-client-quickstart"
このコマンドは、Infinispan Clientエクステンションをインポートして、新しいプロジェクトを生成します。
Quarkusプロジェクトがすでに設定されている場合、プロジェクトのベースディレクトリで次のコマンドを実行することで、 infinispan-client
エクステンションをプロジェクトに追加できます:
quarkus extension add infinispan-client
./mvnw quarkus:add-extension -Dextensions='infinispan-client'
./gradlew addExtension --extensions='infinispan-client'
これにより、pom.xml
に以下が追加されます:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-infinispan-client</artifactId>
</dependency>
implementation("io.quarkus:quarkus-infinispan-client")
annotationProcessor 'org.infinispan.protostream:protostream-processor:4.6.1.Final' (1)
1 | アノテーションベースのシリアライゼーションでファイル生成を有効にするため、Gradleビルドで必須 |
Greeting POJOを作成
Greeting
POJOを使用して雛形を少しずつ作っていきましょう。次の内容で、 src/main/java/org/acme/infinispan/client/Greeting.java
ファイルを作成します:
package org.acme.infinispan.client;
import org.infinispan.protostream.annotations.Proto;
@Proto (1)
public record Greeting(String name, String message) {} (2)
1 | Protostreamによってマーシャリングされるレコードにタグを付けるアノテーションが必要なだけです。 |
なお、今回はJava標準のシリアライズは使用しません。 Protostream は、Infinispanの一部であるProtobufデータフォーマットに基づいたシリアライズライブラリです。アノテーションベースのAPIを使用して、Protobuf形式でデータを保存します。
Greeting スキーマを作成
GreetingSchema
インターフェイスを使用して、シリアライズスキーマを作成します。以下の内容で、 src/main/java/org/acme/infinispan/client/GreetingSchema.java
ファイルを作成します:
package org.acme.infinispan.client;
import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.ProtoSchema;
@ProtoSchema(includeClasses = Greeting.class) (1)
public interface GreetingSchema extends GeneratedSchema { (2)
}
1 | @ProtoSchema アノテーションで Greeting pojo をインクルードします。 |
2 | Protostream API の GeneratedSchema インターフェースを実装します。 |
Protobuf Schemaは、生成され、クライアント側とInfinispanサーバー側の両方で使用され、以下のような内容になります:
// File name: GreetingSchema.proto
// Generated from : org.acme.infinispan.client.GreetingSchema
syntax = "proto3";
message Greeting {
optional string name = 1;
optional string message = 2;
}
InfinispanのGreetingリソースを作成
以下の内容で、 src/main/java/org/acme/infinispan/client/InfinispanGreetingResource.java
ファイルを作成します:
package org.acme.infinispan.client;
import io.quarkus.infinispan.client.Remote;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import org.infinispan.client.hotrod.RemoteCache;
import java.util.concurrent.CompletionStage;
@Path("/greeting")
public class InfinispanGreetingResource {
@Inject
@Remote("mycache") (1)
RemoteCache<String, Greeting> cache; (2)
@POST
@Path("/{id}")
public CompletionStage<String> postGreeting(String id, Greeting greeting) {
return cache.putAsync(id, greeting) (3)
.thenApply(g -> "Greeting done!")
.exceptionally(ex -> ex.getMessage());
}
@GET
@Path("/{id}")
public CompletionStage<Greeting> getGreeting(String id) {
return cache.getAsync(id); (4)
}
}
1 | キャッシュを使用するには、 @Remote アノテーションを使用します。キャッシュが存在しない場合、 初回アクセス時に デフォルトの設定で作成されます。 |
2 | RemoteCache を注入します。 |
3 | 挨拶の idをキーに、Greeting POJO をバリューとして格納します。 |
4 | id をキーに Greeting POJO を取得します。 |
テストクラスを作成
pom.xml
ファイルを編集し、以下の依存関係を追加します:
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
以下の内容で src/test/java/org/acme/infinispan/client/InfinispanGreetingResourceTest.java
ファイルを作成します:
package org.acme.infinispan.client;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
class InfinispanGreetingResourceTest {
@Test
public void testHelloEndpoint() {
given()
.contentType(ContentType.JSON)
.body("{\"name\":\"Infinispan Client\",\"message\":\"Hello World, Infinispan is up!\"}")
.when()
.post("/greeting/quarkus")
.then()
.statusCode(200);
given()
.when().get("/greeting/quarkus")
.then()
.statusCode(200)
.body(is("{\"name\":\"Infinispan Client\",\"message\":\"Hello World, Infinispan is up!\"}"));
}
}
実行
以下を使ってアプリケーションを実行するだけです:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
Dev Servicesのおかげで、Infinispanサーバが稼働しているはずです。Dev ServicesのUIには、http://localhost:8080/q/dev/
でアクセスできます 。Dev UIにInfinispan UI Panelが表示されるでしょう。
Web Consoleリンクをクリックし、デフォルトの認証情報である |
Greeting サービスとの連携
上記で見てきたように、Greeting APIは2つのRestエンドポイントを公開しています。このセクションでは、挨拶のメッセージを作成し、表示する方法について紹介します。
挨拶のメッセージを作成
次のコマンドで、id が quarkus
の挨拶のメッセージを作成します。
curl -X POST http://localhost:8080/greeting/quarkus -H "Content-Type: application/json" -d '{"name" : "Infinispan Client", "message":"Hello World, Infinispan is up!"}'
サービスは、 Greeting added!
というメッセージで応答するでしょう。
挨拶のメッセージを表示
次のコマンドで、id が quarkus
の挨拶のメッセージを表示します。
curl http://localhost:8080/greeting/quarkus
このサービスは以下のjsonコンテンツで応答するでしょう。
{
"name" : "Infinispan Client",
"message" : "Hello World, Infinispan is up!"
}
Infinispan Server Consoleでキャッシュとコンテンツを表示
要求されたキャッシュが存在しない場合、Quarkusは最初のアクセス時にDefault設定でキャッシュを作成します。Infinispan Server コンソールを再読み込みして、キャッシュの内容を表示しましょう。Infinispan Server コンソールは、 Infinispan Server REST API を使用しています。JSON形式に変換するProtobuf Encodingのおかげで、コンテンツをJSONで表示できます。
本番環境での設定
この時点で、QuarkusはInfinispan Dev Serviceを使用して、Infinispanサーバーを実行し、アプリケーションを設定しています。しかし、実稼働環境では、独自のInfinispan(またはRed Hat Data Grid)を実行することになります。
以下を使って11222番ポートでInfinispanサーバを起動してください:
docker run -it -p 11222:11222 -e USER="admin" -e PASS="password" quay.io/infinispan/server:latest
次に、 src/main/resources/application.properties
ファイルを開き追加します:
%prod.quarkus.infinispan-client.hosts=localhost:11222 (1)
%prod.quarkus.infinispan-client.username=admin (2)
%prod.quarkus.infinispan-client.password=password (3)
## Docker 4 Mac workaround. Uncomment only if you are using Docker for Mac.
## Read more about it in the Infinispan Reference Guide
# %prod.quarkus.infinispan-client.client-intelligence=BASIC (4)
1 | Infinispanサーバーのアドレスリストをカンマ区切りで設定します。 |
2 | 認証ユーザー名を設定 |
3 | 認証パスワードを設定 |
4 | クライアントのインテリジェンスを設定。Docker for Macを使用する場合は、BASICを回避策として使用します。 |
クライアント・インテリジェンスの変更は、本番環境でのパフォーマンスに影響を与えます。 厳密に必要な場合を除き、クライアントインテリジェンスを変更しないでください。 詳細は Infinispanクライアントエクステンションのリファレンスガイド を参照してください。 |
JVMモードでのパッケージ化と実行
従来の jar ファイルとしてアプリケーションを実行できます。
まず、パッケージ化します:
quarkus build
./mvnw install
./gradlew build
このコマンドは、テストを実行するためのInfinispanインスタンスを起動します。 |
次に、以下を実行してください。
java -jar target/quarkus-app/quarkus-run.jar
ネイティブ実行
ソースコードを変更することなく、このアプリケーションからネイティブ実行可能ファイルを作成することもできます。ネイティブ実行可能ファイルは、JVMへの依存を取り除きます。ターゲットプラットフォーム上でアプリケーションを実行するために必要なすべてのものが実行ファイルに含まれているため、アプリケーションを最小限のリソースオーバーヘッドで実行することができます。
GraalVMは、不要なコードパスを削除するために追加のステップを実行するため、ネイティブ実行可能ファイルのコンパイルには少し時間がかかります。 native
プロファイルを使用して、ネイティブ実行可能ファイルをコンパイルしてください。
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
ビルドが完了したら、実行可能ファイルを次のように実行できます:
./target/infinispan-client-quickstart-1.0.0-SNAPSHOT-runner
さらに詳しく
Quarkus Infinispanエクステンションの詳細については、 Infinispan Clientエクステンションのリファレンスガイド を参照してください。