Using the Infinispan Client

本指南演示了 Quarkus 应用程序如何使用 Infinispan Client 扩展连接到 Infinispan 服务器。

This guide demonstrates how your Quarkus application can connect to an Infinispan server using the Infinispan Client extension.

Prerequisites

include::{includes}/prerequisites.adoc[]* 正在运行的 Docker 环境

Unresolved directive in infinispan-client.adoc - include::{includes}/prerequisites.adoc[] * A working Docker environment

Architecture

在本指南中,我们将使用 Infinispan RemoteCache APIgetAsyncputAsync 操作来公开一个 Greeting Rest API,用于创建和显示问候消息。

In this guide, we are going to expose a Greeting Rest API to create and display greeting messages by using the Infinispan RemoteCache API and getAsync and putAsync operations.

我们将使用 Quarkus Infinispan Client 扩展来连接到 Infinispan 进行交互。

We’ll be using the Quarkus Infinispan Client extension to connect to interact with Infinispan.

Solution

我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。

We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.

克隆 Git 存储库: git clone {quickstarts-clone-url},或下载 {quickstarts-archive-url}[存档]。

Clone the Git repository: git clone {quickstarts-clone-url}, or download an {quickstarts-archive-url}[archive].

解决方案位于 infinispan-client-quickstart directory 中。

The solution is located in the infinispan-client-quickstart directory.

Creating the Maven Project

首先,我们需要一个新项目。使用以下命令创建一个新项目:

First, we need a new project. Create a new project with the following command:

Unresolved directive in infinispan-client.adoc - include::{includes}/devtools/create-app.adoc[]

此命令生成一个新项目,导入 Infinispan Client 扩展。

This command generates a new project, importing the Infinispan Client extension.

如果您已经配置了 Quarkus 项目,您可以通过在项目基础目录中运行以下命令来将 infinispan-client 扩展添加到项目中:

If you already have your Quarkus project configured, you can add the infinispan-client extension to your project by running the following command in your project base directory:

Unresolved directive in infinispan-client.adoc - include::{includes}/devtools/extension-add.adoc[]

这会将以下内容添加到构建文件中:

This will add the following to your build file:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-infinispan-client</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-infinispan-client")
annotationProcessor 'org.infinispan.protostream:protostream-processor:4.6.1.Final' 1
1 Mandatory in the Gradle build to enable the generation of the files in the annotation based serialization

Creating the Greeting POJO

我们将使用 Greeting POJO 对增量进行建模。创建 src/main/java/org/acme/infinispan/client/Greeting.java 文件,并添加以下内容:

We are going to model our increments using the Greeting POJO. Create the src/main/java/org/acme/infinispan/client/Greeting.java file, with the following content:

package org.acme.infinispan.client;

import org.infinispan.protostream.annotations.Proto;

@Proto (1)
public record Greeting(String name, String message) {} (2)
1 You only need an annotation to tag the record to be marshalled by Protostream

请注意,我们不打算使用 Java 序列化。 Protostream 是 Infinispan 的基于 Protobuf 数据格式的序列化库。使用基于注释的 API,我们将数据存储为 Protobuf 格式。

Note that we are not going to use Java serialization. Protostream is a serialization library based on Protobuf data format part of Infinispan. Using an annotation based API, we will store our data in Protobuf format.

Creating the Greeting Schema

我们将使用 GreetingSchema 接口创建序列化架构。创建 src/main/java/org/acme/infinispan/client/GreetingSchema.java 文件,并添加以下内容:

We are going to create our serialization schema using the GreetingSchema interface. Create the src/main/java/org/acme/infinispan/client/GreetingSchema.java file, with the following content:

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 Includes the Greeting pojo with the @ProtoSchema annotation
2 Extends GeneratedSchema Protostream API interface

在客户端和 Infinispan 服务器端生成并使用的 Protobuf 模式将具有以下内容:

The Protobuf Schema that will be generated and used both on client and Infinispan Server side, will have the following content:

// File name: GreetingSchema.proto
// Generated from : org.acme.infinispan.client.GreetingSchema

syntax = "proto3";

message Greeting {

   optional string name = 1;

   optional string message = 2;
}

Creating the Infinispan Greeting Resource

创建 src/main/java/org/acme/infinispan/client/InfinispanGreetingResource.java 文件,内容如下:

Create the src/main/java/org/acme/infinispan/client/InfinispanGreetingResource.java file, with the following content:

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 Use the @Remote annotation to use a cache. If the cache does not exist, will be created with a default configuration on first access.
2 Inject the RemoteCache
3 Put the greeting id as a key and the Greeting pojo as a value
4 Get the greeting by id as the key

Creating the test class

编辑 pom.xml 文件以添加以下依赖项:

Edit the pom.xml file to add the following dependency:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
</dependency>

创建 src/test/java/org/acme/infinispan/client/InfinispanGreetingResourceTest.java 文件,内容如下:

Create the src/test/java/org/acme/infinispan/client/InfinispanGreetingResourceTest.java file with the following content:

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!\"}"));
    }
}

Get it running

我们只需要使用以下内容运行应用程序:

We just need to run the application using:

Unresolved directive in infinispan-client.adoc - include::{includes}/devtools/dev.adoc[]

由于 Dev 服务,我们应该让 Infinispan 服务器运行。我们可以通过 http://localhost:8080/q/dev/ 访问 Dev 服务 UI。Dev UI 应该显示 Infinispan UI 面板。

We should have the Infinispan server running thanks to the Dev Services. We can access the Dev Services UI through http://localhost:8080/q/dev/. The Dev UI should display the Infinispan UI Panel.

dev ui infinispan

单击 Web 控制台链接并使用 adminpassword 默认凭据进行日志记录。Quarkus 已将 Protobuf 模式上传到模式选项卡,该模式用于使用 Protobuf 在服务器上编组 Greeting POJO。查看 Infinispan Dev Services Guide 以了解更多信息。

Click on the Web Console link and log using admin and password default credentials. Quarkus has uploaded into the Schemas Tab the Protobuf Schema that is needed to marshall on the server the Greeting POJO with Protobuf. Check the Infinispan Dev Services Guide to learn more.

Interacting with the Greeting Service

如上所述,问候 API 公开了两个 Rest 端点。在本节中,我们将学习如何创建和显示问候消息。

As we have seen above, the Greeting API exposes two Rest endpoints. In this section we are going to see how to create and display a greeting message.

Creating a Greeting Message

使用以下命令,我们将创建一个 ID 为 quarkus 的问候消息。

With the following command, we will create a greeting message with the 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! 消息进行响应。

The service should respond with a Greeting added! message.

Displaying a Greeting Message

使用以下命令,我们将显示 ID 为 quarkus 的问候消息。

With the following command, we will display the greeting message with the id quarkus.

curl  http://localhost:8080/greeting/quarkus

该服务应使用以下 json 内容进行响应。

The service should respond with the following json content.

{
  "name" : "Infinispan Client",
  "message" : "Hello World, Infinispan is up!"
}

Display the cache and content with the Infinispan Server Console

如果请求的高速缓存不存在,则 Quarkus 会在首次访问时使用默认配置创建高速缓存。我们应该能够重新加载 Infinispan 服务器控制台并显示高速缓存的内容。Infinispan 服务器控制台使用 Infinispan Server REST API。由于 Protobuf 编码将内容转换为 JSON 格式,因此可以用 JSON 显示内容。

If a requested cache does not exist, Quarkus creates a cache with a Default configuration on first access. We should be able to reaload the Infinispan Server Console and display the content of the Cache. The Infinispan Server Console uses the Infinispan Server REST API. The content can be displayed in JSON thanks to the Protobuf Encoding that converts to JSON format.

infinispan console client guide

Configuring for production

至此,Quarkus 使用 Infinispan Dev 服务来运行 Infinispan 服务器并配置应用程序。但是,在生产环境中,您将运行自己的 Infinispan(或 Red Hat Data Grid)。

At this point, Quarkus uses the Infinispan Dev Service to run an Infinispan server and configure the application. However, in production, you will run your own Infinispan (or Red Hat Data Grid).

使用以下命令在 11222 端口上启动一个 Infinispan 服务器:

Let’s start an Infinispan server on the port 11222 using:

docker run -it -p 11222:11222 -e USER="admin" -e PASS="password" quay.io/infinispan/server:latest

然后,打开 src/main/resources/application.properties 文件并添加:

Then, open the src/main/resources/application.properties file and add:

%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 Sets Infinispan Server address list, separated with commas
2 Sets the authentication username
3 Sets the authentication password
4 Sets the client intelligence. Use BASIC as a workaround if using Docker for Mac.

客户端情报的变化会影响您在生产中的性能。除非对您的情况绝对必要,否则不要更改客户端情报。在 Infinispan Client extension reference guide 中阅读更多内容。

Client intelligence changes impact your performance in production. Don’t change the client intelligence unless strictly necessary for your case. Read more in the Infinispan Client extension reference guide.

Packaging and running in JVM mode

您可以将应用程序作为常规 jar 文件运行。

You can run the application as a conventional jar file.

首先,我们需要对其进行打包:

First, we will need to package it:

Unresolved directive in infinispan-client.adoc - include::{includes}/devtools/build.adoc[]

此命令将启动一个 Infinispan 实例来执行测试。

This command will start an Infinispan instance to execute the tests.

然后运行它:

Then run it:

java -jar target/quarkus-app/quarkus-run.jar

Running Native

您还可以从此应用程序创建本机可执行程序,而无需进行任何源代码更改。本机可执行程序消除了对 JVM 的依赖:在本机可执行程序中包含了在目标平台上运行应用程序所需的一切,从而允许应用程序以最小的资源开销运行。

You can also create a native executable from this application without making any source code changes. A native executable removes the dependency on the JVM: everything needed to run the application on the target platform is included in the executable, allowing the application to run with minimal resource overhead.

编译本机可执行程序需要花费更长时间,因为 GraalVM 会执行额外的步骤来删除不必要的代码路径。使用 native 配置文件来编译本机可执行程序:

Compiling a native executable takes a bit longer, as GraalVM performs additional steps to remove unnecessary codepaths. Use the native profile to compile a native executable:

Unresolved directive in infinispan-client.adoc - include::{includes}/devtools/build-native.adoc[]

构建完成后,您可以使用以下命令运行可执行程序:

Once the build is finished, you can run the executable with:

./target/infinispan-client-quickstart-1.0.0-SNAPSHOT-runner

Going further

要了解有关 Quarkus Infinispan 扩展的更多信息,请查看 the Infinispan Client extension reference guide

To learn more about the Quarkus Infinispan extension, check the Infinispan Client extension reference guide.