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

Quarkus - JMSの使用

このガイドでは、QuarkusアプリケーションがApache Qpid JMS AMQPクライアント、またはApache ActiveMQ Artemis JMSクライアントを介してJMSメッセージングを使用する方法を説明します。

この技術は、previewと考えられています。

preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリストGitHub の課題管理 で受け付けています。

For a full list of possible statuses, check our FAQ entry.

前提条件

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

  • 約15分

  • IDE

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

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

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

  • 実行中のArtemisサーバー、または起動するためのDocker

アーキテクチャ

このガイドでは、あるコンポーネントが(ランダムな)価格を生成します。これらの価格は、JMS クライアントを使用してキュー ( prices ) に書き込まれます。別のコンポーネントが prices のキューから読み込み、最新の価格を保存します。データは、JAX-RSリソースからフェッチボタンを使用してブラウザで取得することができます。

このガイドは、すぐ下で詳しく説明する Apache Qpid JMS AMQP クライアントを介して使うこともできますし、 後ほど詳しく説明する ように、Apache ActiveMQ Artemis JMS クライアントを介して使うこともできます。

Qpid JMS - AMQP

以下の詳細な手順では、 Quarkus Qpid JMSエクステンション を使用して Apache Qpid JMS クライアントを使用します。Qpid JMSは、ワイヤプロトコルとしてAMQP 1.0 ISO標準を使用しているため、ActiveMQ Artemis、ActiveMQ 5、Qpid Broker-J、Qpid Dispatchルーター、Azure Service Busなど、さまざまなAMQP 1.0サーバーやサービスで使用することができます。

ソリューション

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

Git リポジトリをクローンします。 git clone https://github.com/amqphub/quarkus-qpid-jms-quickstart.git または アーカイブ をダウンロードします。

Mavenプロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します。

CLI
quarkus create app org.acme:jms-quickstart \
    --extension=resteasy-reactive,qpid-jms \
    --no-code
cd jms-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストール方法については、Quarkus CLIガイドをご参照ください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.11.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=jms-quickstart \
    -Dextensions="resteasy-reactive,qpid-jms" \
    -DnoCode
cd jms-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

This command generates a new project importing the quarkus-qpid-jms extension:

pom.xml
<dependency>
    <groupId>org.amqphub.quarkus</groupId>
    <artifactId>quarkus-qpid-jms</artifactId>
</dependency>
build.gradle
implementation("org.amqphub.quarkus:quarkus-qpid-jms")

ブローカーの開始

Then, we need an AMQP broker. In this case we will use an Apache ActiveMQ Artemis server. You can follow the instructions from the Apache Artemis website or start a broker via docker using the ArtemisCloud container image:

docker run -it --rm -p 8161:8161 -p 61616:61616 -p 5672:5672 -e AMQ_USER=quarkus -e AMQ_PASSWORD=quarkus quay.io/artemiscloud/activemq-artemis-broker:0.1.4

価格のプロデューサー

以下の内容の src/main/java/org/acme/jms/PriceProducer.java ファイルを作成します。

package org.acme.jms;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;

import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;

/**
 * A bean producing random prices every 5 seconds and sending them to the prices JMS queue.
 */
@ApplicationScoped
public class PriceProducer implements Runnable {

    @Inject
    ConnectionFactory connectionFactory;

    private final Random random = new Random();
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    void onStart(@Observes StartupEvent ev) {
        scheduler.scheduleWithFixedDelay(this, 0L, 5L, TimeUnit.SECONDS);
    }

    void onStop(@Observes ShutdownEvent ev) {
        scheduler.shutdown();
    }

    @Override
    public void run() {
        try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
            context.createProducer().send(context.createQueue("prices"), Integer.toString(random.nextInt(100)));
        }
    }
}

価格のコンシューマー

価格のコンシューマーはJMSから価格を読み取り、最後の1つを保存します。以下の内容で src/main/java/org/acme/jms/PriceConsumer.java ファイルを作成します。

package org.acme.jms;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.jms.ConnectionFactory;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.Message;

import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;

/**
 * A bean consuming prices from the JMS queue.
 */
@ApplicationScoped
public class PriceConsumer implements Runnable {

    @Inject
    ConnectionFactory connectionFactory;

    private final ExecutorService scheduler = Executors.newSingleThreadExecutor();

    private volatile String lastPrice;

    public String getLastPrice() {
        return lastPrice;
    }

    void onStart(@Observes StartupEvent ev) {
        scheduler.submit(this);
    }

    void onStop(@Observes ShutdownEvent ev) {
        scheduler.shutdown();
    }

    @Override
    public void run() {
        try (JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
            JMSConsumer consumer = context.createConsumer(context.createQueue("prices"));
            while (true) {
                Message message = consumer.receive();
                if (message == null) return;
                lastPrice = message.getBody(String.class);
            }
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}

価格リソース

最後に、前回の価格を表示するための簡単なJAX-RSリソースを作成してみましょう。 src/main/java/org/acme/jms/PriceResource.java ファイルを以下の内容で作成します。

package org.acme.jms;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * A simple resource showing the last price.
 */
@Path("/prices")
public class PriceResource {

    @Inject
    PriceConsumer consumer;

    @GET
    @Path("last")
    @Produces(MediaType.TEXT_PLAIN)
    public String last() {
        return consumer.getLastPrice();
    }
}

HTMLページ

最後に、変換された価格をSSEを使って読み込むHTMLページ。

以下の内容の src/main/resources/META-INF/resources/prices.html ファイルを作成します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Prices</title>

    <link rel="stylesheet" type="text/css"
          href="https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly.min.css">
    <link rel="stylesheet" type="text/css"
          href="https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly-additions.min.css">
</head>
<body>
<div class="container">

    <h2>Last price</h2>
    <div class="row">
    <p class="col-md-12"><button id="fetch">Fetch</button>The last price is <strong><span id="content">N/A</span>&nbsp;&euro;</strong>.</p>
    </div>
</div>
</body>
<script>
    document.getElementById("fetch").addEventListener("click", function() {
        fetch("/prices/last").then(function (response) {
            response.text().then(function (text) {
                document.getElementById("content").textContent = text;
            })
        })
    })
</script>
</html>

特筆すべきものは何もありません。フェッチするたびにページが更新されます。

Qpid JMSのプロパティーの設定

ConnectionFactoryを注入する際にエクステンションで使用するQpid JMSプロパティーを設定する必要があります。

これは、 src/main/resources/application.properties ファイルで行います。

# Configures the Qpid JMS properties.
quarkus.qpid-jms.url=amqp://localhost:5672
quarkus.qpid-jms.username=quarkus
quarkus.qpid-jms.password=quarkus

設定の詳細については、 Quarkus Qpid JMS のドキュメントを参照してください。

実行

手順に従うことで、Artemis サーバーを起動できます。あとは、アプリケーションを使用して実行するだけです。

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

ブラウザーで http://localhost:8080/prices.html を開いてください。

ネイティブ実行

以下でネイティブ実行可能ファイルをビルドすることができます。

CLI
quarkus build --native
Maven
./mvnw package -Dnative
Gradle
./gradlew build -Dquarkus.package.type=native

あるいは、GraalVMをインストールしていない場合は、代わりにDockerを使ってネイティブ実行可能ファイルをビルドすることもできます。

CLI
quarkus build --native --no-tests -Dquarkus.native.container-build=true
# The --no-tests flag is required only on Windows and macOS.
Maven
./mvnw package -Dnative -Dquarkus.native.container-build=true
Gradle
./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true

次に、以下を実行してください。

./target/jms-quickstart-1.0.0-SNAPSHOT-runner

ブラウザーで http://localhost:8080/prices.html を開いてください。


Artemis JMS

上記の手順はQpid JMS AMQPクライアントを使用して詳細に説明していますが、このガイドはArtemis JMSクライアントでも使用することができます。個々のステップの多くは、 Qpid JMSの上記の詳細 と全く同じです。個々のコンポーネントコードも同じです。唯一の違いは、最初のプロジェクト作成のための依存関係と、使用される設定プロパティーです。これらの変更点は以下に詳述されており、上記のシーケンス中の同等のステップで代用する必要があります。

ソリューション

完成した例に進むことができます。

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

Artemis JMS ソリューションは jms-quickstart ディレクトリ にあります。

Mavenプロジェクトの作成

以下のコマンドで新規プロジェクトを作成します。

CLI
quarkus create app org.acme:jms-quickstart \
    --extension=resteasy-reactive,artemis-jms \
    --no-code
cd jms-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストール方法については、Quarkus CLIガイドをご参照ください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.11.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=jms-quickstart \
    -Dextensions="resteasy-reactive,artemis-jms" \
    -DnoCode
cd jms-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

This creates a new project importing the quarkus-artemis-jms extension:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-artemis-jms</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-artemis-jms")

プロジェクトが作成されたら、上記の詳細手順の ブローカーの開始 から再開し、application.properties ファイルの設定まで進め、代わりに以下のArtemisの設定を使用します。

Artemisのプロパティーの設定

Artemis の接続プロパティーを設定する必要があります。これは src/main/resources/application.properties ファイルで行います。

# Configures the Artemis properties.
quarkus.artemis.url=tcp://localhost:61616
quarkus.artemis.username=quarkus
quarkus.artemis.password=quarkus

Artemisのプロパティーを設定した状態で、 実行 から上記の手順を再開することができます。

設定リファレンス

To know more about how to configure the Artemis JMS client, have a look at the documentation of the extension.