Camel Extensions for Quarkus によるアプリケーション開発
Camel Extensions for Quarkus によるアプリケーション開発
概要
はじめに
多様性を受け入れるオープンソースの強化
Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。この取り組みは膨大な作業を要するため、今後の複数のリリースで段階的に用語の置き換えを実施して参ります。詳細は、Red Hat CTO である Chris Wright のメッセージ をご覧ください。
第1章 Camel Extensions for Quarkus を使用したアプリケーションの開発の概要
本ガイドは、Camel Extensions for Quarkus の上に Camel アプリケーションを作成する開発者向けです。
Camel Extensions for Quarkus でサポートされる Camel コンポーネントには、関連する Camel Extensions for Quarkus エクステンションがあります。このディストリビューションでサポートされる Camel Extensions for Quarkus エクステンションに関する詳細は、Camel Extensions for Quarkus リファレンスガイドを参照してください。
ネイティブモード での Camel Extensions for Quarkus は、テクノロジープレビュー機能としてのみご利用いただけます。
第2章 依存関係の管理
2.1. 新規プロジェクトを起動する Quarkus ツール
特定の Camel Extensions for Quarkus リリースは、特定の Quarkus リリースでのみ動作するはずです。
新規プロジェクトで適切な依存関係バージョンを取得する最も簡単で分かりやすい方法は、Quarkus ツールのいずれかを使用することです。
- code.quarkus.redhat.com: オンラインプロジェクトジェネレーター
- Quarkus Maven プラグイン
これらのツールを使用すると、エクステンションを選択し、新しい Maven プロジェクトの基礎を固めることができます。
生成される pom.xml
は以下のようになります。
<project> ... <properties> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>com.redhat.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version> <!-- The latest 2.2.x version from https://maven.repository.redhat.com/ga/com/redhat/quarkus/platform/quarkus-bom --> </quarkus.platform.version> ... </properties> <dependencyManagement> <dependencies> <!-- The BOMs managing the dependency versions --> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-camel-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- The extensions you chose in the project generator tool --> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-sql</artifactId> <!-- No explicit version required here and below --> </dependency> ... </dependencies> ... </project>
利用可能なエクステンションの領域は、Quarkus Core、Camel Quarkus、およびその他のサードパーティー参加プロジェクト (Hazelcast、Cassandra、Kogito、OptaPlanner など) にまたがるものです。
BOM は Bill of Materials を指します。この pom.xml
の主目的は、アーティファクトのバージョンを管理することです。これにより、BOM をプロジェクトにインポートするエンドユーザーは、互いに機能するアーティファクトの特定バージョンを気にする必要はありません。つまり、pom.xml
の <depependencyManagement>
セクションに BOM をインポートすると、指定の BOM によって管理される依存関係のバージョンを指定する必要がありません。
pom.xml
に含まれる特定の BOM は、整合性のある BOM の最小セットを選択するよう設定されたジェネレーターツールを使用して選択するエクステンションによって異なります。
pom.xml
ファイルのいずれかの BOM で管理されていないエクステンションを後で追加する場合、適切な BOM を手動で検索する必要はありません。quarkus-maven-plugin
を使用すると、エクステンションを選択でき、ツールは必要に応じて適切な BOM を追加します。quarkus-maven-plugin
を使用して、BOM バージョンをアップグレードすることもできます。
com.redhat.quarkus.platform
BOM は相互に調整されるため、アーティファクトが複数の BOM で管理されている場合は、常に同じバージョンで管理されることになります。これには、アプリケーション開発者が、独立した各種プロジェクトからの個々のアーティファクトの互換性に注意する必要がないという利点があります。
第3章 Camel ルートの定義
Camel Extensions for Quarkus は、Camel ルートを定義する Java DSL 言語をサポートします。
3.1. Java DSL
org.apache.camel.builder.RouteBuilder
を拡張し、そこで利用可能な Fluent Builder メソッドを使用するのが、Camel ルートを定義する最も一般的な方法です。以下は、タイマーコンポーネントを使用したルートの簡単な例です。
import org.apache.camel.builder.RouteBuilder; public class TimerRoute extends RouteBuilder { @Override public void configure() throws Exception { from("timer:foo?period=1000") .log("Hello World"); } }
3.1.1. エンドポイント DSL
Camel 3.0 以降、Fluent ビルダーを使用して Camel エンドポイントを定義することもできます。以下は前述の例と同等です。
import org.apache.camel.builder.RouteBuilder; import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; public class TimerRoute extends RouteBuilder { @Override public void configure() throws Exception { from(timer("foo").period(1000)) .log("Hello World"); } }
すべての Camel コンポーネントの Builder メソッドは camel-quarkus-core
で利用できますが、ルートが適切に機能するように、指定のコンポーネントのエクステンションを依存関係として追加する必要があります。上記の例では、camel-quarkus-timer
になります。
第4章 設定
Camel Quarkus は、デフォルトでは Quarkus アプリケーションライフサイクルに応じて開始/停止される Camel Context Bean を自動的に設定およびデプロイします。設定ステップは、Quarkus の拡張フェーズ中のビルド時に実行され、Camel Quarkus 固有の quarkus.camel.*
プロパティーを使用して調整できる Camel Quarkus エクステンションによって実行されます。
quarkus.camel.*
設定プロパティーは、個別のエクステンションページに記載されています (Camel Quarkus Core 等を参照)。
設定が完了すると、最小の Camel Runtime がアセンブルされ、RUNTIME_INIT フェーズで起動します。
4.1. Camel コンポーネントの設定
4.1.1. application.properties
プロパティーによって Apache Camel のコンポーネントおよびその他の要素を設定するには、アプリケーションが camel-quarkus-core
に直接、または推移的な推移的に依存するようにしてください。ほとんどの Camel Quarkus エクステンションは camel-quarkus-core
に依存するため、通常は明示的に追加する必要はありません。
camel-quarkus-core
は、Camel Main から Camel Quarkus への機能を提供します。
以下の例では、application.properties
経由で LogComponent
に特定の ExchangeFormatter
を設定します。
camel.component.log.exchange-formatter = #class:org.apache.camel.support.processor.DefaultExchangeFormatter camel.component.log.exchange-formatter.show-exchange-pattern = false camel.component.log.exchange-formatter.show-body-type = false
4.1.2. CDI
CDI を使用して、コンポーネントをプログラムで設定することもできます。
推奨の方法は、ComponentAddEvent
を監視し、ルートおよび CamelContext
を起動する前にコンポーネントを設定することです。
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import org.apache.camel.quarkus.core.events.ComponentAddEvent; import org.apache.camel.component.log.LogComponent; import org.apache.camel.support.processor.DefaultExchangeFormatter; @ApplicationScoped public static class EventHandler { public void onComponentAdd(@Observes ComponentAddEvent event) { if (event.getComponent() instanceof LogComponent) { /* Perform some custom configuration of the component */ LogComponent logComponent = ((LogComponent) event.getComponent()); DefaultExchangeFormatter formatter = new DefaultExchangeFormatter(); formatter.setShowExchangePattern(false); formatter.setShowBodyType(false); logComponent.setExchangeFormatter(formatter); } } }
4.1.2.1. @Named
コンポーネントインスタンスの生成
または、@Named
プロデューサーメソッドでコンポーネントを作成し、設定できます。これは、Camel がコンポーネントの URI スキームを使用してレジストリーからコンポーネントをルックアップするため機能します。たとえば、LogComponent
Camel の場合は bean という名前の log
を検索します。
@Named
コンポーネント Bean の生成は通常は機能しますが、一部のコンポーネントで少し問題が発生する可能性があることに注意してください。
Camel Quarkus エクステンションは、以下のいずれかを行う場合があります。
- デフォルトの Camel コンポーネントタイプのカスタムサブタイプを渡します。Vert.x WebSocket エクステンション の例を参照してください。
- コンポーネントの Quarkus 固有のカスタマイズをいくつか実施します。JPA エクステンション の例を参照してください。
これらのアクションは、独自のコンポーネントインスタンスの作成時に実行されないため、オブザーバーメソッドでコンポーネントを設定することが推奨される方法です。
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import org.apache.camel.component.log.LogComponent;
import org.apache.camel.support.processor.DefaultExchangeFormatter;
@ApplicationScoped
public class Configurations {
/**
* Produces a {@link LogComponent} instance with a custom exchange formatter set-up.
*/
@Named("log") 1
LogComponent log() {
DefaultExchangeFormatter formatter = new DefaultExchangeFormatter();
formatter.setShowExchangePattern(false);
formatter.setShowBodyType(false);
LogComponent component = new LogComponent();
component.setExchangeFormatter(formatter);
return component;
}
}
- 1
- メソッドの名前が同じであれば、
@Named
アノテーションの"log"
引数は省略できます。
4.2. 規則による設定
camel-quarkus-core
プロパティーによる Camel の設定をサポートする他に、規則を使用して Camel 動作を設定できます。たとえば、CDI コンテナーに単一の ExchangeFormatter
インスタンスがある場合、その Bean を LogComponent
に自動的に接続します。
4.3. メータリングラベル
メータリングラベルを Camel Quarkus Pod に追加し、OpenShift Metering Operator を使用して Red Hat サブスクリプションの詳細を確認できます。
メータリングラベルは、Operator またはテンプレートがデプロイおよび管理する Pod に追加しないでください。
Camel Quarkus は以下のメータリングラベルを使用できます。
-
com.company: Red_Hat
-
rht.prod_name: Red_Hat_Integration
-
rht.prod_ver: 2021.Q4
-
rht.comp: "Camel-Quarkus"
-
rht.comp_ver: 2.2.0
-
rht.subcomp: {sub-component-name}
-
rht.subcomp_t: application
第5章 Camel Quarkus の Contexts and Dependency Injection (CDI)
CDI は Quarkus の中心的なロールを果たします。Camel Quarkus は優れたサポートを提供します。
たとえば、@Inject
、@ConfigProperty
、および同様のアノテーションを使用して、Bean と設定値を Camel RouteBuilder
に注入することができます。以下に例を示します。
import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.apache.camel.builder.RouteBuilder; import org.eclipse.microprofile.config.inject.ConfigProperty; @ApplicationScoped 1 public class TimerRoute extends RouteBuilder { @ConfigProperty(name = "timer.period", defaultValue = "1000") 2 String period; @Inject Counter counter; @Override public void configure() throws Exception { fromF("timer:foo?period=%s", period) .setBody(exchange -> "Incremented the counter: " + counter.increment()) .to("log:cdi-example?showExchangePattern=false&showBodyType=false"); } }
- 1
@ApplicationScoped
アノテーションは@Inject
および@ConfigProperty
がRouteBuilder
で機能するために必要です。@ApplicationScoped
Bean は CDI コンテナーによって管理され、それらのライフサイクルは、単純なRouteBuilder
のライフサイクルよりも複雑です。つまり、RouteBuilder
で@ApplicationScoped
を使用すると、ブート時にデメリットが生じることがあるため、本当に必要なときにのみRouteBuilder
に@ApplicationScoped
のアノテーションを付ける必要があります。- 2
timer.period
プロパティーの値は、サンプルプロジェクトのsrc/main/resources/application.properties
で定義されます。
詳細は、Quarkus Dependency Injection ガイド を参照してください。
5.1. CamelContext
へのアクセス
CamelContext
にアクセスするには、Bean に注入します。
import javax.inject.Inject; import javax.enterprise.context.ApplicationScoped; import java.util.stream.Collectors; import java.util.List; import org.apache.camel.CamelContext; @ApplicationScoped public class MyBean { @Inject CamelContext context; public List<String> listRouteIds() { return context.getRoutes().stream().map(Route::getId).sorted().collect(Collectors.toList()); } }
5.2. CDI および Camel Bean コンポーネント
5.2.1. 名前による Bean の参照
名前でルート定義で Bean を参照するには、Bean に @Named("myNamedBean")
および @ApplicationScoped
。@RegisterForReflection
アノテーションは、ネイティブモードでは重要です。
import javax.enterprise.context.ApplicationScoped; import javax.inject.Named; import io.quarkus.runtime.annotations.RegisterForReflection; @ApplicationScoped @Named("myNamedBean") @RegisterForReflection public class NamedBean { public String hello(String name) { return "Hello " + name + " from the NamedBean"; } }
次に、ルート定義で myNamedBean
名を使用できます。
import org.apache.camel.builder.RouteBuilder; public class CamelRoute extends RouteBuilder { @Override public void configure() { from("direct:named") .to("bean:namedBean?method=hello"); } }
第6章 可観測性
6.1. ヘルス/liveness チェック
ヘルス/liveness チェックは MicroProfile Health エクステンションでサポートされます。
Camel Health API または Quarkus MicroProfile Health を使用して設定できます。
設定されたチェックはすべて標準の MicroProfile Health エンドポイント URL で利用できます。
6.2. メトリクス
メトリクスを公開するための MicroProfile メトリクス を提供します。
一部の基本的な Camel メトリクスは追加設定なしで提供され、ルートに追加メトリクスを設定して補足できます。
メトリクスは、標準の Quarkus メトリクスエンドポイントで利用できます。
第7章 ネイティブモード
ネイティブモードでのアプリケーションのコンパイルおよびテストについての詳細は、Quarkus アプリケーションのネイティブ実行可能ファイルへのコンパイルガイドの ネイティブ実行可能ファイルの作成 を参照してください。
テクノロジープレビューの機能は、Red Hat の本番環境のサービスレベルアグリーメント (SLA) ではサポートされず、機能的に完全ではないことがあるため、Red Hat は本番環境での使用は推奨しません。テクノロジープレビューの機能は、最新の技術をいち早く提供して、開発段階で機能のテストやフィードバックの収集を可能にするために提供されます。詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。
7.1. 文字エンコーディング
デフォルトでは、すべての Charset
がネイティブモードで利用できる訳ではありません。
Charset.defaultCharset(), US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16
アプリケーションでこのセットに含まれていないエンコーディングが必要な場合や、ネイティブモードで UnsupportedCharsetException
が出力された場合は、以下のエントリーを application.properties
に追加してください。
quarkus.native.add-all-charsets = true
Quarkus ドキュメントの quarkus.native.add-all-charsets も参照してください。
7.2. Locale
デフォルトでは、JVM のデフォルトロケールのビルドのみがネイティブイメージに含まれます。Quarkus では、application.properties
でロケールを設定する方法が提供され、これにより LANG
および LC_*
環境変数に依存しなくても良いようになります。
quarkus.native.user-country=US quarkus.native.user-language=en
また、複数のロケールをネイティブイメージに組み込むことや、Mandel コマンドラインオプション -H:IncludeLocales=fr,en
、H:+IncludeAllLocales
、および -H:DefaultLocale=de
を使用してデフォルトのロケールを選択することもサポートされます。これらは、Quarkus quarkus.native.additional-build-args
プロパティーで設定できます。
7.3. ネイティブ実行可能ファイルへのリソースの埋め込み
Class.getResource()
、Class.getResourceAsStream()
、ClassLoader.getResource()
、ClassLoader.getResourceAsStream()
などを介してアクセスされるリソースは、ネイティブ実行ファイルに含めるために明示的に一覧表示する必要があります。
これは、以下のように application.properties
ファイルの Quarkus quarkus.native.resources.includes
および quarkus.native.resources.excludes
プロパティーを使用して実行できます。
quarkus.native.resources.includes = docs/*,images/* quarkus.native.resources.excludes = docs/ignored.adoc,images/ignored.png
上記の例では、docs/included.adoc
および images/included.png
という名前のリソースはネイティブ実行可能ファイルに組み込まれ、docs/ignored.adoc
および images/ignored.png
のリソースはネイティブの実行ファイルに組み込まれません。
resources.includes
および resources.excludes
は、どちらも Ant-path スタイルの glob パターンのコンマ区切りリストです。
詳細は、Camel Extensions for Quarkus Reference を参照してください。
7.4. ネイティブモードでの onException 句の使用
ネイティブモードで camel onException 処理を使用する場合、反映させるためにアプリケーション開発者は例外クラスを登録する必要があります。
たとえば、onException 処理のある camel コンテキストは以下のようになります。
onException(MyException.class).handled(true); from("direct:route-that-could-produce-my-exception").throw(MyException.class);
リフレクションのために、クラス mypackage.MyException
を登録する必要があります。詳細は、リフレクションのためのクラスの登録 を参照してください。
7.5. リフレクションのためのクラスの登録
デフォルトでは、動的リフレクションはネイティブモードでは使用できません。リフレクションアクセスが必要なクラスは、コンパイル時にリフレクション用に登録する必要があります。
多くの場合、Quarkus エクステンションはリフレクションを必要とするクラスを検出して自動的に登録できるため、アプリケーション開発者は注意する必要はありません。
ただし、状況によっては、Quarkus のエクステンションはクラスの一部を見逃す場合があるので、アプリケーション開発者が登録を行う必要があります。これには 2 つの方法があります。
-
@io.quarkus.runtime.annotations.RegisterForReflection
アノテーションを使用して、使用するクラスを登録するか、targets
属性を使用してサードパーティークラスを登録することもできます。 application.properties
のquarkus.camel.native.reflection
オプション:quarkus.camel.native.reflection.include-patterns = org.apache.commons.lang3.tuple.* quarkus.camel.native.reflection.exclude-patterns = org.apache.commons.lang3.tuple.*Triple
これらのオプションが適切に機能するには、選択したクラスが含まれるアーティファクトに Jandex インデックス ('META-INF/jandex.idx') が含まれるか、'application.properties'の'quarkus.index-dependency.*' オプションを使用して、インデックス化のために登録する必要があります。たとえば、
quarkus.index-dependency.commons-lang3.group-id = org.apache.commons quarkus.index-dependency.commons-lang3.artifact-id = commons-lang3
7.6. シリアル化のためのクラスの登録
quarkus.camel.native.reflection.serialization-enabled
でシリアル化サポートを要求すると、CamelSerializationProcessor.BASE_SERIALIZATION_CLASSES に一覧表示されているクラスはシリアル化のために自動的に登録されます。
ユーザーは @RegisterForReflection(serialization = true)
を使用してさらにクラスを登録できます。