Red Hat build of Apache Camel for Quarkus を使用したアプリケーションの開発
Red Hat build of Apache Camel for Quarkus を使用したアプリケーションの開発
概要
はじめに
Red Hat build of Apache Camel ドキュメントに関するフィードバック
エラーを報告したり、ドキュメントの改善を提案したりするには、Red Hat Jira アカウントにログインし、課題を送信してください。Red Hat Jira アカウントをお持ちでない場合は、アカウントを作成するように求められます。
手順
- 次のリンクをクリックして チケットを作成 します。
- Summary に課題の簡単な説明を入力します。
- Description に課題や機能拡張の詳細な説明を入力します。問題があるドキュメントのセクションへの URL も記載してください。
- Submit をクリックすると、課題が作成され、適切なドキュメントチームに転送されます。
第1章 Red Hat build of Apache Camel for Quarkus を使用したアプリケーション開発の概要
このガイドは、Red Hat build of Apache Camel for Quarkus 上で Camel アプリケーションを作成する開発者を対象としています。
Red Hat build of Apache Camel for Quarkus でサポートされている Camel コンポーネントには、関連する Red Hat build of Apache Camel for Quarkus エクステンションがあります。このディストリビューションでサポートされている Red Hat build of Apache Camel for Quarkus エクステンションの詳細は、Red Hat build of Apache Camel for Quarkus エクステンション ガイドを参照してください。
第2章 依存関係の管理
特定の Red Hat build of Apache Camel for Quarkus リリースは、特定の Quarkus リリースでのみ動作するように設計されています。
2.1. 新規プロジェクトを起動する Quarkus ツール
新規プロジェクトで適切な依存関係バージョンを取得する最も簡単でわかりやすい方法は、Quarkus ツールのいずれかを使用することです。
- code.quarkus.redhat.com - オンラインプロジェクトジェネレーター
- Quarkus Maven プラグイン
これらのツールを使用すると、エクステンションを選択し、新しい Maven プロジェクトのスキャフォールディングを行うことができます。
利用可能なエクステンションの領域は、Quarkus Core、Camel Quarkus、およびその他のサードパーティー参加プロジェクト (Hazelcast、Cassandra、Kogito、OptaPlanner など) にまたがるものです。
生成される 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 3.20.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>
<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 3.20.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>
BOM は "Bill of Materials" を指します。この pom.xml
の主目的は、アーティファクトのバージョンを管理することです。これにより、BOM をプロジェクトにインポートするエンドユーザーが、互いに機能するアーティファクトのバージョンに注意を払う必要がなくなります。つまり、pom.xml
の <depependencyManagement>
セクションに BOM をインポートすると、その BOM によって管理される依存関係のバージョンを指定する必要がなくなります。
どの BOM が pom.xml
ファイルに保存されるかは、ジェネレーターツールで選択したエクステンションによって異なります。ジェネレーターツールは、一貫した最小限のセットを選択します。
pom.xml
ファイルの BOM で管理されていないエクステンションを後で追加する場合も、適切な BOM を手動で検索する必要はありません。
quarkus-maven-plugin
を使用してエクステンションを選択すると、ツールが必要に応じて適切な BOM を追加します。また、quarkus-maven-plugin
を使用して、BOM バージョンをアップグレードすることもできます。
com.redhat.quarkus.platform
の BOM は相互に調整されます。つまり、アーティファクトが複数の BOM で管理されている場合は、常に同じバージョンで管理されます。これには、アプリケーション開発者が、独立した各種プロジェクトからの個々のアーティファクトの互換性に注意する必要がないという利点があります。
2.2. 他の BOM との統合
camel-quarkus-bom
を他の BOM と組み合わせる場合は、インポートの順序が優先順位を定義するため、これらをインポートする順番を慎重に検討してください。
つまり、my-foo-bom
を camel-quarkus-bom
より前にインポートした場合、my-foo-bom
で定義されたバージョンが優先されます。この優先順位が希望するものかどうかは、my-foo-bom
と camel-quarkus-bom
の間に重複があるかどうか、および優先順位の高いバージョンが camel-quarkus-bom
で管理される残りのアーティファクトと連携するかどうかによって決まります。
第3章 Camel ルートの定義
Red Hat build of Apache Camel for Quarkus では、以下の言語を使用して Camel ルートを定義できます。
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"); } }
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.2. エンドポイント DSL
Camel 3.0 以降、Fluent Builder を使用して 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"); } }
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
になります。
3.3. XML IO DSL
XML で Camel ルート、rests、またはテンプレートを設定するには、Camel XML パーサーの依存関係をクラスパスに追加する必要があります。Camel Quarkus 1.8.0 以降、https://docs.redhat.com/en/documentation/developing_applications_with_red_hat_build_of_apache_camel_for_quarkus/4.10/html-single/red_hat_build_of_apache_camel_for_quarkus_reference/ #extensions-xml-io-dsl[camel-quarkus-xml-io-dsl]
が最適な選択肢です。
Camel Main では、ルート、REST DSL、ルートテンプレート などのリソース XML ファイルの場所を指すプロパティーを設定できます。
camel.main.routes-include-pattern = routes/routes.xml, file:src/main/routes/rests.xml, file:src/main/rests/route-template.xml
camel.main.routes-include-pattern = routes/routes.xml, file:src/main/routes/rests.xml, file:src/main/rests/route-template.xml
camel.main.routes-include-pattern = *./routes.xml
のようなパスグロビングは、現在ネイティブモードでは機能しません。
ルート
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <route id="xml-route"> <from uri="timer:from-xml?period=1000"/> <log message="Hello XML!"/> </route> </routes>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<route id="xml-route">
<from uri="timer:from-xml?period=1000"/>
<log message="Hello XML!"/>
</route>
</routes>
Bean で XML ルートを使用する場合は、beanType=org.apache.SomeClass
のようにクラス名を参照する必要があります。このような場合には、リフレクションのためにクラスをネイティブモードで登録する必要がある場合があります。詳細は、ネイティブモード のセクションを参照してください。
< blueprint> 要素のある
はサポートされていません。
<beans
> または Blueprint XML を持つ Spring XML
ルート XML は、次のように簡素化されたバージョンである必要があります。
REST DSL
<rests xmlns="http://camel.apache.org/schema/spring"> <rest id="greeting" path="/greeting"> <get path="/hello"> <to uri="direct:greet"/> </get> </rest> </rests>
<rests xmlns="http://camel.apache.org/schema/spring">
<rest id="greeting" path="/greeting">
<get path="/hello">
<to uri="direct:greet"/>
</get>
</rest>
</rests>
ルートテンプレート
<routeTemplates xmlns="http://camel.apache.org/schema/spring"> <routeTemplate id="myTemplate"> <templateParameter name="name"/> <templateParameter name="greeting"/> <templateParameter name="myPeriod" defaultValue="3s"/> <route> <from uri="timer:{{name}}?period={{myPeriod}}"/> <setBody><simple>{{greeting}} ${body}</simple></setBody> <log message="${body}"/> </route> </routeTemplate> </routeTemplates>
<routeTemplates xmlns="http://camel.apache.org/schema/spring">
<routeTemplate id="myTemplate">
<templateParameter name="name"/>
<templateParameter name="greeting"/>
<templateParameter name="myPeriod" defaultValue="3s"/>
<route>
<from uri="timer:{{name}}?period={{myPeriod}}"/>
<setBody><simple>{{greeting}} ${body}</simple></setBody>
<log message="${body}"/>
</route>
</routeTemplate>
</routeTemplates>
3.4. YAML DSL
YAML を使用してルートを設定するには、camel-quarkus-yaml-dsl
依存関係をクラスパスに追加する必要があります。
Camel Main では、ルート、REST DSL、および Route テンプレート 定義が含まれる YAML ファイルの場所を指すプロパティーを設定できます。
camel.main.routes-include-pattern = routes/routes.yaml, routes/rests.yaml, rests/route-template.yaml
camel.main.routes-include-pattern = routes/routes.yaml, routes/rests.yaml, rests/route-template.yaml
ルート
- route: id: "my-yaml-route" from: uri: "timer:from-yaml?period=1000" steps: - set-body: constant: "Hello YAML!" - to: "log:from-yaml"
- route:
id: "my-yaml-route"
from:
uri: "timer:from-yaml?period=1000"
steps:
- set-body:
constant: "Hello YAML!"
- to: "log:from-yaml"
REST DSL
- rest: get: - path: "/greeting" to: "direct:greet" - route: id: "rest-route" from: uri: "direct:greet" steps: - set-body: constant: "Hello YAML!"
- rest:
get:
- path: "/greeting"
to: "direct:greet"
- route:
id: "rest-route"
from:
uri: "direct:greet"
steps:
- set-body:
constant: "Hello YAML!"
ルートテンプレート
- route-template: id: "myTemplate" parameters: - name: "name" - name: "greeting" defaultValue: "Hello" - name: "myPeriod" defaultValue: "3s" from: uri: "timer:{{name}}?period={{myPeriod}}" steps: - set-body: expression: simple: "{{greeting}} ${body}" - log: "${body}" - templated-route: route-template-ref: "myTemplate" parameters: - name: "name" value: "tick" - name: "greeting" value: "Bonjour" - name: "myPeriod" value: "5s"
- route-template:
id: "myTemplate"
parameters:
- name: "name"
- name: "greeting"
defaultValue: "Hello"
- name: "myPeriod"
defaultValue: "3s"
from:
uri: "timer:{{name}}?period={{myPeriod}}"
steps:
- set-body:
expression:
simple: "{{greeting}} ${body}"
- log: "${body}"
- templated-route:
route-template-ref: "myTemplate"
parameters:
- name: "name"
value: "tick"
- name: "greeting"
value: "Bonjour"
- name: "myPeriod"
value: "5s"
第4章 Camel Quarkus でのルートのテスト
4.1. Camel Quarkus エクステンションのテスト
テストは、Camel ルートが長期にわたって期待どおりに動作することを確認するための良い方法です。まだの場合は、「Camel Quarkus User guide」の First Steps セクションと Quarkus ドキュメントの Testing your application セクションをご一読ください。
Quarkus のコンテキストでルートをテストする場合、ローカル統合テストを作成することが推奨されます。これには、JVM モードとネイティブモードの両方をカバーできるという利点があります。
JVM モードでは、CamelTestSupport
スタイルのテスト を使用できます。
4.1.1. JVM モードでの実行
JVM モードでは、@QuarkusTest
アノテーションを使用して Quarkus をブートストラップし、@Test
ロジックが実行される 前 に Camel ルートを起動します。
以下に例を示します。
import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; @QuarkusTest class MyTest { @Test public void test() { // Use any suitable code that sends test data to the route and then assert outcomes ... } }
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
@QuarkusTest
class MyTest {
@Test
public void test() {
// Use any suitable code that sends test data to the route and then assert outcomes
...
}
}
サンプル実装は Camel Quarkus ソースにあります。
4.1.2. ネイティブモードでの実行
サポートされているすべてのエクステンションに対して、アプリケーションがネイティブモードで動作することを常にテストしてください。
それぞれの JVM モードクラスからロジックを継承することにより、JVM モード用に定義されたテストロジックを再利用できます。
@QuarkusIntegrationTest
アノテーションを追加して、Quarkus JUnit エクステンションに、テスト対象のアプリケーションをネイティブイメージにコンパイルし、テストを実行する前にイメージを起動するように指示します。
import io.quarkus.test.junit.QuarkusIntegrationTest; @QuarkusIntegrationTest class MyIT extends MyTest { ... }
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
class MyIT extends MyTest {
...
}
サンプル実装は Camel Quarkus ソースにあります。
4.1.3. @QuarkusTest
と @QuarkusIntegrationTest
の違い
ネイティブ実行可能ファイルは、バイトコードではなくネイティブコードであるため、実行に JVM を必要とせず、また JVM で実行することもできません。
従来の JVM を使用して実行するために、テストをネイティブコードにコンパイルしても意味はありません。
そのため、テストとアプリケーション間の通信は、ネットワーク (HTTP/REST、またはアプリケーションが使用するその他のプロトコル)、ファイルシステム (ログファイルなど) の監視、またはその他のプロセス間通信を介して行う必要があります。
4.1.3.1. JVM モードでの @QuarkusTest
JVM モードでは、@QuarkusTest
のアノテーションが付けられたテストは、テスト対象のアプリケーションと同じ JVM で実行されます。
これは、@Inject
を使用して、アプリケーションからテストコードに Bean を追加できることを意味します。
@jakarta.enterprise.inject.Alternative
および @jakarta.annotation.Priority
を使用して、新しい Bean を定義したり、アプリケーションから Bean をオーバーライドしたりすることもできます。
4.1.3.2. ネイティブモードでの @QuarkusIntegrationTest
ネイティブモードでは、@QuarkusIntegrationTest
のアノテーションが付けられたテストは、実行中のネイティブアプリケーションとは別のプロセスでホストされている JVM で実行されます。
この重要な結果として、テストとネイティブアプリケーション間のすべての通信は、次の 1 つ以上の形式を取る必要があります。
- ネットワークの呼び出し。通常は、HTTP またはアプリケーションがサポートするその他のネットワークプロトコルです。
-
ファイルシステムの変更を監視します。(例: Camel
file
エンドポイント経由) - その他の種類のプロセス間通信。
QuarkusIntegrationTest
は、@QuarkusTest
では利用できない追加機能を提供します。
- JVM モードでは、Quarkus ビルドによって生成された実行可能なアプリケーション JAR を起動してテストできます。
- ネイティブモードでは、Quarkus ビルドによって作成されたネイティブアプリケーションを起動してテストできます。
- コンテナーイメージをビルドに追加すると、コンテナーが起動し、それに対してテストが実行されます。
QuarkusIntegrationTest
の詳細は、Quarkus testing guide を参照してください。
4.1.4. 外部サービスによるテスト
4.1.4.1. Testcontainers
アプリケーションは、メッセージングブローカー、データベース、その他のサービスなどの外部リソースにアクセスする必要がある場合があります。
対象のサービスのコンテナーイメージが利用可能な場合は、Testcontainers を使用して、テスト中にサービスを起動および設定できます。
4.1.4.1.1. QuarkusTestResourceLifecycleManager
を使用して設定データを渡す
アプリケーションを正常に動作させるためには、多くの場合、接続設定データ (ホスト、ポート、ユーザー、リモートサービスのパスワード) をアプリケーションの起動前に渡すことが不可欠です。
Quarkus エコシステムでは、QuarkusTestResourceLifecycleManager
がこの目的を果たします。
start()
メソッドで 1 つ以上の Testcontainer を起動し、メソッドから接続設定を Map
の形式で返すことができます。
このマップのエントリーは、モードに応じてさまざまな方法でアプリケーションに渡されます。
-
ネイティブモード: コマンドライン (
-Dkey=value
) - JVM モード: 特別な MicroProfile 設定プロバイダー
コマンドラインおよび MicroProfile 設定は、application.properties
ファイルの設定よりも優先されます。
import java.util.Map; import java.util.HashMap; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; public class MyTestResource implements QuarkusTestResourceLifecycleManager { private GenericContainer<?> myContainer; @Override public Map<String, String> start() { // Start the needed container(s) myContainer = new GenericContainer(DockerImageName.parse("my/image:1.0.0")) .withExposedPorts(1234) .waitingFor(Wait.forListeningPort()); myContainer.start(); // Pass the configuration to the application under test // You can also pass camel component property names / values to automatically configure Camel components return new HashMap<>() {{ put("my-container.host", container.getHost()); put("my-container.port", "" + container.getMappedPort(1234)); }}; } @Override public void stop() { // Stop the needed container(s) myContainer.stop(); ... } }
import java.util.Map;
import java.util.HashMap;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
public class MyTestResource implements QuarkusTestResourceLifecycleManager {
private GenericContainer<?> myContainer;
@Override
public Map<String, String> start() {
// Start the needed container(s)
myContainer = new GenericContainer(DockerImageName.parse("my/image:1.0.0"))
.withExposedPorts(1234)
.waitingFor(Wait.forListeningPort());
myContainer.start();
// Pass the configuration to the application under test
// You can also pass camel component property names / values to automatically configure Camel components
return new HashMap<>() {{
put("my-container.host", container.getHost());
put("my-container.port", "" + container.getMappedPort(1234));
}};
}
@Override
public void stop() {
// Stop the needed container(s)
myContainer.stop();
...
}
}
@QuarkusTestResource
を使用して、テストクラスから定義済みのテストリソースを参照します。
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(MyTestResource.class) class MyTest { ... }
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
@QuarkusTestResource(MyTestResource.class)
class MyTest {
...
}
サンプル実装は Camel Quarkus ソースにあります。
4.1.4.2. WireMock
ライブエンドポイントが利用できない、信頼性が低い、コストがかかる場合などには、テストをライブエンドポイントに接続する代わりに、サードパーティーのサービスおよび API との HTTP インタラクションをスタブできます。
WireMock を使用すると、HTTP インタラクションをモックおよび記録できます。これは、さまざまなコンポーネントエクステンション用に Camel Quarkus テストスイート全体で広く使用されています。
4.1.4.2.1. WireMock のセットアップ
手順
WireMock サーバーをセットアップします。
注記テストを行う Camel コンポーネントを常に設定して、すべての HTTP 対話を WireMock プロキシー経由で渡すようにします。これは、API エンドポイント URL を決定するコンポーネントプロパティーを設定することで実現できます。
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import java.util.HashMap; import java.util.Map; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class WireMockTestResource implements QuarkusTestResourceLifecycleManager { private WireMockServer server; @Override public Map<String, String> start() { // Setup & start the server server = new WireMockServer( wireMockConfig().dynamicPort() ); server.start(); // Stub an HTTP endpoint. WireMock also supports a record and playback mode // https://wiremock.org/docs/record-playback/ server.stubFor( get(urlEqualTo("/api/greeting")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody("{\"message\": \"Hello World\"}"))); // Ensure the camel component API client passes requests through the WireMock proxy Map<String, String> conf = new HashMap<>(); conf.put("camel.component.foo.server-url", server.baseUrl()); return conf; } @Override public void stop() { if (server != null) { server.stop(); } } }
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import java.util.HashMap; import java.util.Map; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class WireMockTestResource implements QuarkusTestResourceLifecycleManager { private WireMockServer server; @Override public Map<String, String> start() { // Setup & start the server server = new WireMockServer( wireMockConfig().dynamicPort() ); server.start(); // Stub an HTTP endpoint. WireMock also supports a record and playback mode // https://wiremock.org/docs/record-playback/ server.stubFor( get(urlEqualTo("/api/greeting")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody("{\"message\": \"Hello World\"}"))); // Ensure the camel component API client passes requests through the WireMock proxy Map<String, String> conf = new HashMap<>(); conf.put("camel.component.foo.server-url", server.baseUrl()); return conf; } @Override public void stop() { if (server != null) { server.stop(); } } }
Copy to Clipboard Copied! -
テストクラスに
@QuarkusTestResource
アノテーションがあり、適切なテストリソースクラスが値として指定されていることを確認します。WireMock サーバーは、すべてのテストが実行される前に起動され、すべてのテストが終了するとシャットダウンされます。
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(WireMockTestResource.class) class MyTest { ... }
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
@QuarkusTestResource(WireMockTestResource.class)
class MyTest {
...
}
WireMock サーバーは、すべてのテストが実行される前に起動し、すべてのテストが終了するとシャットダウンします。
サンプルの実装は、Camel Quarkus 統合テストソースツリーにあります。
4.1.5. CamelQuarkusTestSupport
での CamelTestSupport
スタイルのテスト
Camel Quarkus 2.13.0 以降、CamelQuarkusTestSupport
をテストに使用できます。これは CamelTestSupport
の後継で、Quarkus では適切に機能しません。
CamelQuarkusTestSupport
は、JVM モードでのみ機能します。ネイティブモードでテストする必要がある場合は、上記の代替テストストラテジーのいずれかを使用します。
4.1.5.1. JVM モードでの CamelQuarkusTestSupport
によるテスト
次の依存関係をモジュール (できれば test
スコープ内) に追加します。
<dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-junit5</artifactId> <scope>test</scope> </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
次のように、テストで CamelQuarkusTestSupport
を使用できます。
@QuarkusTest @TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance) public class SimpleTest extends CamelQuarkusTestSupport { ... }
@QuarkusTest
@TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance)
public class SimpleTest extends CamelQuarkusTestSupport {
...
}
4.1.5.2. テスト用の CamelContext
のカスタマイズ
設定プロファイル、CDI Bean、オブザーバー、mocks などを使用してテスト用に CamelContext
をカスタマイズできます。createCamelContext
メソッドをオーバーライドして、CamelContext
と直接対話することもできます。
createCamelContext
を使用する場合は、新しい CamelContext
をインスタンス化して返さ ないようにしてください。代わりに、super.createCamelContext()
を呼び出して、返された CamelContext
を必要に応じて変更します。このルールに従わないと、例外が発生します。
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Override protected CamelContext createCamelContext() throws Exception { // Must call super to get a handle on the application scoped CamelContext CamelContext context = super.createCamelContext(); // Apply customizations context.setTracing(true); // Return the modified CamelContext return context; } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Override
protected CamelContext createCamelContext() throws Exception {
// Must call super to get a handle on the application scoped CamelContext
CamelContext context = super.createCamelContext();
// Apply customizations
context.setTracing(true);
// Return the modified CamelContext
return context;
}
}
4.1.5.3. テスト用のルートの設定
アプリケーション内の RouteBuilder
を拡張するすべてのクラスのルートは、CamelContext
に自動的に追加されます。同様に、camel.main.routes-include-pattern
から設定された XML または YAML ルートも読み込まれます。
これは必ずしもテストに適切であるとは限りません。設定プロパティーを使用して、テスト時にどのルートをロードするかを制御します。
-
quarkus.camel.routes-discovery.include-patterns
-
quarkus.camel.routes-discovery.exclude-patterns
-
camel.main.routes-include-pattern
-
camel.main.routes-exclude-pattern
createRouteBuilder
をオーバーライドして、テストクラスごとにテスト固有のルートを定義することもできます。
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") .transform().simple("Hello ${body}") .to("mock:result"); } }; } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Test
void testGreeting() {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:start", "World");
mockEndpoint.assertIsSatisified();
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.transform().simple("Hello ${body}")
.to("mock:result");
}
};
}
}
4.1.5.4. CamelContext テストライフサイクル
CamelTestSupport
と比較した CamelQuarkusTestSupport
の主な違いの 1 つは、CamelContext
ライフサイクルがどのように管理されるかです。
Camel Quarkus では、ランタイムによって単一の CamelContext
が自動的に作成されます。デフォルトでは、この CamelContext
はすべてのテスト間で共有され、これは、テストスイート全体が実行中は起動状態のままになります。
これにより、テストに予期しない副作用が生じる可能性があります。テスト間で CamelContext
を再起動する必要がある場合は、カスタム テストプロファイル を作成して、テスト対象のアプリケーションを強制的に再起動できます。
たとえば、テストプロファイルを定義するには、次のようにします。
@QuarkusTest class MyTestProfile implements QuarkusTestProfile { ... }
@QuarkusTest
class MyTestProfile implements QuarkusTestProfile {
...
}
次に、@TestProfile
を使用してテストクラスで参照します。
// @TestProfile will trigger the application to be restarted @TestProfile(MyTestProfile.class) @QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { ... }
// @TestProfile will trigger the application to be restarted
@TestProfile(MyTestProfile.class)
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
...
}
CamelContext
の stop()
メソッドと start()
メソッドを呼び出して手動で再起動できません。これにより、例外が発生します。
4.1.5.5. 例
4.1.5.5.1. シンプルな RouteBuilder
およびテストクラス
シンプルな RouteBuilder
:
public class MyRoutes extends RouteBuilder { @Override public void configure() { from("direct:start") .transform().simple("Hello ${body}") .to("mock:result"); } }
public class MyRoutes extends RouteBuilder {
@Override
public void configure() {
from("direct:start")
.transform().simple("Hello ${body}")
.to("mock:result");
}
}
メッセージペイロードを direct:start
エンドポイントに送信するテストを実行します。
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Test
void testGreeting() {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:start", "World");
mockEndpoint.assertIsSatisified();
}
}
4.1.5.5.2. AdviceWith
の使用
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BeforeEach public void beforeEach() throws Exception { AdviceWith.adviceWith(this.context, "advisedRoute", route -> { route.replaceFromWith("direct:replaced"); }); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").routeId("advisedRoute") .transform().simple("Hello ${body}") .to("mock:result"); } }; } @Test void testAdvisedRoute() throws Exception { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:replaced", "World"); mockEndpoint.assertIsSatisfied(); } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@BeforeEach
public void beforeEach() throws Exception {
AdviceWith.adviceWith(this.context, "advisedRoute", route -> {
route.replaceFromWith("direct:replaced");
});
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("advisedRoute")
.transform().simple("Hello ${body}")
.to("mock:result");
}
};
}
@Test
void testAdvisedRoute() throws Exception {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:replaced", "World");
mockEndpoint.assertIsSatisfied();
}
}
4.1.5.5.3. アドバイスの明示的な有効化
アドバイスを明示的に有効にする 場合は、AdviceWith
のセットアップを完了するときに startRouteDefinitions
を呼び出す必要があります。
startRouteDefinitions
を呼び出す必要があるのは、アドバイスされて いない ルートが設定されている場合のみです。
4.1.5.6. 制限
4.1.5.6.1. CamelTestSupport
から継承されたテストライフサイクルメソッド
CamelQuarkusTestSupport
は、CamelTestSupport
から一部のテストライフサイクルメソッドを継承します。ただし、これらは使用すべきではなく、代わりに CamelQuarkusTestSupport
の同等のメソッドに置き換えられます。
CamelTestSupport ライフサイクルメソッド | CamelQuarkusTestSupport 相当 |
---|---|
|
|
|
|
|
|
|
|
4.1.5.6.2. カスタム Camel レジストリーの作成はサポートされていません
createCamelRegistry
の CamelQuarkusTestSupport
実装は UnsupportedOperationException
を出力します。
オブジェクトを Camel レジストリーにバインドまたはバインド解除する必要がある場合は、次のいずれかの方法で実行できます。
名前付き CDI Bean を生成する
public class MyBeanProducers { @Produces @Named("myBean") public MyBean createMyBean() { return new MyBean(); } }
public class MyBeanProducers { @Produces @Named("myBean") public MyBean createMyBean() { return new MyBean(); } }
Copy to Clipboard Copied! -
createCamelContext
をオーバーライドし (上記の例を参照)、camelContext.getRegistry().bind ("foo"、fooBean)
を呼び出す。 @BindToRegistry
アノテーションを使用する。@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BindToRegistry("myBean") MyBean myBean = new MyBean(); }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BindToRegistry("myBean") MyBean myBean = new MyBean(); }
Copy to Clipboard Copied! 注記個々のテストクラスから Camel レジストリーにバインドされた Bean は、テストスイートの実行中は保持されます。テストの期待値によっては、予期しない結果が生じる可能性があります。これを回避するには、テストプロファイルを使用して
CamelContext
を再起動できます。
第5章 設定
Camel Quarkus は、デフォルトでは Quarkus アプリケーションライフサイクルに応じて起動/停止する Camel Context Bean を自動的に設定およびデプロイします。設定ステップは、Quarkus の拡張フェーズ中のビルド時に実行され、Camel Quarkus 固有の quarkus.camel.*
プロパティーを使用して調整できる Camel Quarkus エクステンションによって実行されます。
quarkus.camel.*
設定プロパティーは、個々のエクステンションページに記載されています。たとえば、Camel Quarkus Core を参照してください。
設定が完了すると、最小の Camel Runtime がアセンブルされ、RUNTIME_INIT フェーズで起動します。
5.1. Camel コンポーネントの設定
5.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
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
5.1.2. CDI
CDI を使用して、コンポーネントをプログラムで設定することもできます。
推奨される方法は、ComponentAddEvent
を監視し、ルートおよび CamelContext
を起動する前にコンポーネントを設定することです。
import jakarta.enterprise.context.ApplicationScoped; import jakarta.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); } } }
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.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);
}
}
}
5.1.2.1. @Named
コンポーネントインスタンスの生成
別の方法として、@Named
プロデューサーメソッドでコンポーネントを作成および設定できます。これは、Camel がコンポーネント URI スキームを使用してレジストリーからコンポーネントを検索する際に機能します。たとえば、LogComponent
Camel の場合は bean という名前の log
を検索します。
@Named
コンポーネント Bean の生成は通常は機能しますが、一部のコンポーネントで軽微な問題が発生する可能性があります。
Camel Quarkus エクステンションは、以下のいずれかを行う場合があります。
- デフォルトの Camel コンポーネントタイプのカスタムサブタイプを渡す。Vert.x WebSocket エクステンション の例を参照してください。
- コンポーネントの Quarkus 固有のカスタマイズを実行する。JPA エクステンション の例を参照してください。
これらのアクションは、独自のコンポーネントインスタンスを作成する場合には実行されないため、オブザーバーメソッドでコンポーネントを設定する方法を推奨します。
import jakarta.enterprise.context.ApplicationScoped; import jakarta.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") LogComponent log() { DefaultExchangeFormatter formatter = new DefaultExchangeFormatter(); formatter.setShowExchangePattern(false); formatter.setShowBodyType(false); LogComponent component = new LogComponent(); component.setExchangeFormatter(formatter); return component; } }
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.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")
LogComponent log() {
DefaultExchangeFormatter formatter = new DefaultExchangeFormatter();
formatter.setShowExchangePattern(false);
formatter.setShowBodyType(false);
LogComponent component = new LogComponent();
component.setExchangeFormatter(formatter);
return component;
}
}
- 1
- メソッドの名前が同じであれば、
@Named
アノテーションの"log"
引数は省略できます。
5.2. 規則による設定
プロパティーによる Camel の設定に加え、camel-quarkus-core
では、規則を使用して Camel の動作を設定できます。たとえば、CDI コンテナーに単一の ExchangeFormatter
インスタンスがある場合は、その Bean を LogComponent
に自動的に接続します。
第6章 Camel Quarkus のコンテキストと依存性注入 (CDI)
CDI は Quarkus で中心的な役割を果たしています。また、Camel Quarkus も CDI に対して優れたサポートを提供します。
たとえば、@Inject
、@ConfigProperty
、および同様のアノテーションを使用して、Bean と設定値を Camel RouteBuilder
に注入することができます。以下に例を示します。
import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.apache.camel.builder.RouteBuilder; import org.eclipse.microprofile.config.inject.ConfigProperty; @ApplicationScoped public class TimerRoute extends RouteBuilder { @ConfigProperty(name = "timer.period", defaultValue = "1000") 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"); } }
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.camel.builder.RouteBuilder;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@ApplicationScoped
public class TimerRoute extends RouteBuilder {
@ConfigProperty(name = "timer.period", defaultValue = "1000")
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 guide を参照してください。
6.1. CamelContext
へのアクセス
CamelContext
にアクセスするには、CamelContext を Bean に注入します。
import jakarta.inject.Inject; import jakarta.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()); } }
import jakarta.inject.Inject;
import jakarta.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());
}
}
6.2. @EndpointInject
と @Produce
プレーン Camel または SpringBoot 上の Camel から @org.apache.camel.EndpointInject
と @org.apache.camel.Produce
を使用することに慣れている場合は、これらを Quarkus でも引き続き使用できます。
次のユースケースは、org.apache.camel.quarkus:camel-quarkus-core
によってサポートされています。
import jakarta.enterprise.context.ApplicationScoped; import org.apache.camel.EndpointInject; import org.apache.camel.FluentProducerTemplate; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; @ApplicationScoped class MyBean { @EndpointInject("direct:myDirect1") ProducerTemplate producerTemplate; @EndpointInject("direct:myDirect2") FluentProducerTemplate fluentProducerTemplate; @EndpointInject("direct:myDirect3") DirectEndpoint directEndpoint; @Produce("direct:myDirect4") ProducerTemplate produceProducer; @Produce("direct:myDirect5") FluentProducerTemplate produceProducerFluent; }
import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.EndpointInject;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
@ApplicationScoped
class MyBean {
@EndpointInject("direct:myDirect1")
ProducerTemplate producerTemplate;
@EndpointInject("direct:myDirect2")
FluentProducerTemplate fluentProducerTemplate;
@EndpointInject("direct:myDirect3")
DirectEndpoint directEndpoint;
@Produce("direct:myDirect4")
ProducerTemplate produceProducer;
@Produce("direct:myDirect5")
FluentProducerTemplate produceProducerFluent;
}
direct:myDirect*
の代わりに、他の Camel プロデューサーエンドポイント URI を使用できます。
@EndpointInject
と @Produce
は、セッターメソッドではサポートされていません。#2579 を参照してください。
次のユースケースは org.apache.camel.quarkus:camel-quarkus-bean
でサポートされています。
import jakarta.enterprise.context.ApplicationScoped; import org.apache.camel.Produce; @ApplicationScoped class MyProduceBean { public interface ProduceInterface { String sayHello(String name); } @Produce("direct:myDirect6") ProduceInterface produceInterface; void doSomething() { produceInterface.sayHello("Kermit") } }
import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.Produce;
@ApplicationScoped
class MyProduceBean {
public interface ProduceInterface {
String sayHello(String name);
}
@Produce("direct:myDirect6")
ProduceInterface produceInterface;
void doSomething() {
produceInterface.sayHello("Kermit")
}
}
6.3. CDI および Camel Bean コンポーネント
6.3.1. 名前による Bean の参照
ルート定義内の Bean を名前で参照するには、Bean に @Named ("myNamedBean")
および @ApplicationScoped
(またはその他の サポートされている スコープ) のアノテーションを付けます。@RegisterForReflection
アノテーションは、ネイティブモードにとって重要です。
import jakarta.enterprise.context.ApplicationScoped; import jakarta.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"; } }
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.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") .bean("myNamedBean", "hello"); /* ... which is an equivalent of the following: */ from("direct:named") .to("bean:myNamedBean?method=hello"); } }
import org.apache.camel.builder.RouteBuilder;
public class CamelRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:named")
.bean("myNamedBean", "hello");
/* ... which is an equivalent of the following: */
from("direct:named")
.to("bean:myNamedBean?method=hello");
}
}
@Named
の代わりに、io.smallrye.common.annotation.Identifier
を使用して Bean に名前を付けて識別することもできます。
import jakarta.enterprise.context.ApplicationScoped; import io.quarkus.runtime.annotations.RegisterForReflection; import io.smallrye.common.annotation.Identifier; @ApplicationScoped @Identifier("myBeanIdentifier") @RegisterForReflection public class MyBean { public String hello(String name) { return "Hello " + name + " from MyBean"; } }
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.smallrye.common.annotation.Identifier;
@ApplicationScoped
@Identifier("myBeanIdentifier")
@RegisterForReflection
public class MyBean {
public String hello(String name) {
return "Hello " + name + " from MyBean";
}
}
次に、Camel ルート内の識別子の値を参照します。
import org.apache.camel.builder.RouteBuilder; public class CamelRoute extends RouteBuilder { @Override public void configure() { from("direct:start") .bean("myBeanIdentifier", "Camel"); } }
import org.apache.camel.builder.RouteBuilder;
public class CamelRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:start")
.bean("myBeanIdentifier", "Camel");
}
}
Red Hat は、Camel ドキュメントの Bean Binding セクションにリストされているすべてのユースケースをサポートすることを目指しています。機能しない Bean バインディングシナリオがある場合は、問題の報告 をぜひお願いいたします。
6.3.2. @Consume
Camel Quarkus 2.0.0 以降、camel-quarkus-bean
アーティファクトにより @org.apache.camel.Consume
がサポートされるようになりました。Camel ドキュメントの Pojo Consuming セクションを参照してください。
次のようなクラスを宣言します。
import org.apache.camel.Consume; public class Foo { @Consume("activemq:cheese") public void onCheese(String name) { ... } }
import org.apache.camel.Consume;
public class Foo {
@Consume("activemq:cheese")
public void onCheese(String name) {
...
}
}
すると、次の Camel ルートが
from("activemq:cheese").bean("foo1234", "onCheese")
from("activemq:cheese").bean("foo1234", "onCheese")
自動的に作成されます。Camel Quarkus は @jakarta.inject.Singleton
と jakarta.inject.Named("foo1234")
を Bean クラスに暗黙的に追加します。1234
は完全修飾クラス名から取得されたハッシュコードです。Bean に何らかの CDI スコープ (@ApplicationScoped
など) または @Named("someName")
がすでに設定されている場合、それらは自動作成されたルートで使用されます。
第7章 可観測性
7.1. ヘルス/liveness チェック
ヘルス/liveness チェックは MicroProfile Health エクステンションでサポートされます。チェックは Camel Health API または Quarkus MicroProfile Health を使用して設定できます。
設定したチェックは、すべて標準の MicroProfile Health エンドポイント URL で利用できます。
7.1.1. 健全性エンドポイント
Camel は、すぐに使用できる Liveness および Readiness チェックをいくつか提供します。これが機能しているかどうかを確認するには、ポート 9000
の /q/health/live
および /q/health/ready
エンドポイントを調べます。
curl -s localhost:9000/q/health/live
$ curl -s localhost:9000/q/health/live
curl -s localhost:9000/q/health/ready
$ curl -s localhost:9000/q/health/ready
JSON 出力には、CamelContext
と各ルートが 'Started' 状態にあるかどうかを確認するためのチェックが含まれます。
このサンプルプロジェクトには、Camel Health API を活用するカスタム Liveness チェッククラス CustomLivenessCheck
とカスタム Readiness チェッククラス CustomReadinessCheck
が含まれています。これらは、健全性 JSON に 'custom-liveness-check' および 'custom-readiness-check' としてリストされます。これらのチェックを 5 回呼び出すたびに、custom-liveness-check
のヘルスステータスが DOWN として報告されます。
MicroProfile Health API を直接活用してチェックを作成することもできます。CamelUptimeHealthCheck
クラスは、Readines チェックを登録する方法を示しています。
7.2. メトリクス
Red Hat は、メトリクスを公開するための MicroProfile メトリクス を提供しています。
一部の基本的な Camel メトリクスは最初から提供されており、ルートに追加メトリクスを設定することで、このメトリクスを補完できます。
メトリックは、標準の Quarkus メトリックエンドポイントで利用できます。
7.3. Camel アプリケーションの監視
アプリケーションを監視することで、メトリクス、健全性チェック、分散トレーシングなど、アプリケーションの動作に関する情報を収集できます。
このセクションでは、Red Hat build of Quarkus の例 に記載されている Observability
の例を使用して、micrometer
による observability を追加します。
前提条件やその他の一般情報は、Camel Quarkus ユーザーガイド を確認してください。
7.3.1. プロジェクトの作成
- 開発 モードで開始する
Maven の
compile
コマンドを実行します。mvn clean compile quarkus:dev
$ mvn clean compile quarkus:dev
Copy to Clipboard Copied! これにより、プロジェクトがコンパイルされ、アプリケーションが起動し、Quarkus ツールがワークスペースの変更を監視できるようになります。
プロジェクトに加えた変更は、実行中のアプリケーションに自動的に反映されます。
ヒント詳細は、Camel Quarkus ユーザーガイド の開発モードのセクションを参照してください。
7.3.2. メトリクスを有効にする
Camel Quarkus で可観測性機能を有効にするには、プロジェクトの pom.xml ファイルに追加の依存関係を追加する必要があります。最も重要なのは、camel-quarkus-opentelemetry
と quarkus-micrometer-registry-prometheus
です。
プロジェクトの
pom.xml
に依存関係を追加します。<dependencies> ... <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-opentelemetry</artifactId> </dependency> <dependency> <groupId>io.quarkiverse.micrometer.registry</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency> ... </dependencies>
<dependencies> ... <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-opentelemetry</artifactId> </dependency> <dependency> <groupId>io.quarkiverse.micrometer.registry</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency> ... </dependencies>
Copy to Clipboard Copied! これらの依存関係により、Camel Micrometer と Quarkus Micrometer の両方の利点を享受できます。
7.3.3. メーターの作成
カスタムメトリクスのメーターは複数の方法で作成できます。
7.3.3.1. Camel マイクロメータコンポーネントの使用
この方法では Routes.java を使用します。
.to("micrometer:counter:org.acme.observability.greeting-provider?tags=type=events,purpose=example")
.to("micrometer:counter:org.acme.observability.greeting-provider?tags=type=events,purpose=example")
これにより、platform-http:/greeting-provider
エンドポイントへの各呼び出しがカウントされます。
7.3.3.2. CDI 依存性注入の使用
この方法では、MeterRegistry
の CDI 依存性注入を使用します。
@Inject MeterRegistry registry;
@Inject
MeterRegistry registry;
次に、Camel Processor
メソッドで直接使用してメトリクスを公開します。
void countGreeting(Exchange exchange) { registry.counter("org.acme.observability.greeting", "type", "events", "purpose", "example").increment(); }
void countGreeting(Exchange exchange) {
registry.counter("org.acme.observability.greeting", "type", "events", "purpose", "example").increment();
}
from("platform-http:/greeting") .removeHeaders("*") .process(this::countGreeting)
from("platform-http:/greeting")
.removeHeaders("*")
.process(this::countGreeting)
これは、platform-http:/greeting
エンドポイントへの各呼び出しをカウントします。
7.3.3.3. Micrometer アノテーションの使用
この方法では、次のように Bean TimerCounter.java
を定義して、Micrometer アノテーション を使用します。
@ApplicationScoped @Named("timerCounter") public class TimerCounter { @Counted(value = "org.acme.observability.timer-counter", extraTags = { "purpose", "example" }) public void count() { } }
@ApplicationScoped
@Named("timerCounter")
public class TimerCounter {
@Counted(value = "org.acme.observability.timer-counter", extraTags = { "purpose", "example" })
public void count() {
}
}
その後、Camel から Bean EIP を介して呼び出すことができます (TimerRoute.java
を参照)。
.bean("timerCounter", "count")
.bean("timerCounter", "count")
Camel タイマーが起動されるたびにカウンターメトリクスが増加します。
7.3.3.4. メトリクスのブラウジング
メトリクスは、ポート 9000
の /q/metrics
の HTTP エンドポイントで公開されます。
管理エンドポイントには、アプリケーションがリッスンしているポート (8080) とは異なるポート (9000) を使用していることに注意してください。これは、quarkus.management.enabled = true
を介して application.properties
で設定されます。詳細は、Quarkus 管理インターフェイスガイド を参照してください。
すべての Camel メトリクスを表示するには、次を実行します。
curl -s localhost:9000/q/metrics
$ curl -s localhost:9000/q/metrics
以前に作成したメトリクスのみを表示するには、次を実行します。
curl -s localhost:9000/q/metrics | grep -i 'purpose="example"'
$ curl -s localhost:9000/q/metrics | grep -i 'purpose="example"'
および、3 行の異なるメトリクスが表示されます (すべてタイマーによってトリガーされるため、値は同じです)。
Prometheus の出力形式に注意してください。JSON 形式を使用する場合は、Quarkus Micrometer 管理インターフェイス 設定ガイド に従ってください。
7.3.4. トレーシング
Camel Quarkus アプリケーションの問題を診断するには、メッセージのトレースを開始できます。クラウド環境に適した OpenTelemetry 標準を使用します。
プロジェクトの pom.xml
に依存関係 camel-quarkus-opentelemetry
と quarkus-micrometer-registry-prometheus
を追加すれば十分です。
<dependencies> ... <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-opentelemetry</artifactId> </dependency> <dependency> <groupId>io.quarkiverse.micrometer.registry</groupId> <artifactId>quarkus-micrometer-registry-prometheus</artifactId> </dependency> ... </dependencies>
<dependencies>
...
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-opentelemetry</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.micrometer.registry</groupId>
<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>
...
</dependencies>
次に、application.properties
で OpenTelemetry エクスポーターを設定します。
We are using a property placeholder to be able to test this example in convenient way in a cloud environment
# We are using a property placeholder to be able to test this example in convenient way in a cloud environment
quarkus.otel.exporter.otlp.traces.endpoint = http://${TELEMETRY_COLLECTOR_COLLECTOR_SERVICE_HOST:localhost}:4317
その他の OpenTelemetry エクスポーターの詳細は、Camel Quarkus OpenTelemetry 拡張ドキュメント を参照してください。
トレースイベントを表示するには、トレースサーバーを起動します。これを行う簡単には、Docker Compose を使用します。
docker-compose up -d
$ docker-compose up -d
サーバーが稼働している状態で、http://localhost:16686 にアクセスします。次に、'Service' ドロップダウンから 'camel-quarkus-observability' を選択し、'Find Traces' ボタンをクリックします。
platform-http
コンシューマールートは、レイテンシーをシミュレートするためにランダムな遅延を導入するため、各トレースの全体的な時間は異なるはずです。トレースを表示すると、各エンドポイントを介したメッセージエクスチェンジの進捗を示す 6 つのスパンの階層が表示されます。
7.3.5. アプリケーションのパッケージ化と実行
開発が完了したら、アプリケーションをパッケージ化して実行できます。
JVM モードとネイティブモードの詳細は、Camel Quarkus ユーザーガイド の「パッケージ化と実行」セクションを参照してください。
7.3.5.1. JVM モード
mvn clean package java -jar target/quarkus-app/quarkus-run.jar
$ mvn clean package
$ java -jar target/quarkus-app/quarkus-run.jar
...
[io.quarkus] (main) camel-quarkus-examples-... started in 1.163s. Listening on: http://0.0.0.0:8080
7.3.5.2. ネイティブモード
ネイティブモードでは、GraalVM およびその他のツールがインストールされている必要があります。Camel Quarkus ユーザーガイド の前提条件セクションを確認してください。
GraalVM を使用してネイティブ実行可能ファイルを準備するには、次のコマンドを実行します。
mvn clean package -Pnative ./target/*-runner
$ mvn clean package -Pnative
$ ./target/*-runner
...
[io.quarkus] (main) camel-quarkus-examples-... started in 0.013s. Listening on: http://0.0.0.0:8080
...
第8章 ネイティブモード
ネイティブモードでのアプリケーションのコンパイルおよびテストの詳細は、Quarkus アプリケーションのネイティブ実行可能ファイルへのコンパイル ガイドの ネイティブ実行可能ファイルの作成 を参照してください。
8.1. 文字エンコーディング
デフォルトでは、すべての Charset
がネイティブモードで利用できる訳ではありません。
Charset.defaultCharset(), US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16
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.native.add-all-charsets = true
Quarkus ドキュメントの quarkus.native.add-all-charsets も参照してください。
8.2. ロケール
デフォルトでは、JVM のデフォルトロケールのビルドのみがネイティブイメージに含まれます。Quarkus では、application.properties
を介してロケールを設定する方法を提供しているため、LANG
および LC_*
環境変数に依存する必要はありません。
quarkus.native.user-country=US quarkus.native.user-language=en
quarkus.native.user-country=US
quarkus.native.user-language=en
また、複数のロケールをネイティブイメージに組み込むことや、Mandrel コマンドラインオプション -H:IncludeLocales=fr,en
、H:+IncludeAllLocales
、および -H:DefaultLocale=de
を使用してデフォルトのロケールを選択することもサポートされます。これらは、Quarkus quarkus.native.additional-build-args
プロパティーで設定できます。
8.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
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 パススタイルの glob パターンのコンマ区切りリストです。
詳細は、Red Hat build of Apache Camel for Quarkus エクステンション リファレンスを参照してください。
8.4. ネイティブモードでの onException 句の使用
Camel onException
処理 をネイティブモードで使用する場合、ユーザーはリフレクションの例外クラスを登録する必要があります。
たとえば、onException
処理のある camel コンテキストは以下のようになります。
onException(MyException.class).handled(true); from("direct:route-that-could-produce-my-exception").throw(MyException.class);
onException(MyException.class).handled(true);
from("direct:route-that-could-produce-my-exception").throw(MyException.class);
クラス mypackage.MyException
をリフレクション用に登録する必要があります。詳細は、リフレクション用のクラスの登録 を参照してください。
8.5. リフレクション用のクラスの登録
デフォルトでは、動的リフレクションはネイティブモードでは使用できません。リフレクションアクセスが必要なクラスは、コンパイル時にリフレクション用に登録する必要があります。
多くの場合、Quarkus エクステンションはリフレクションを必要とするクラスを検出して自動的に登録できるため、アプリケーション開発者は注意する必要はありません。
ただし、状況によっては、Quarkus のエクステンションはクラスの一部を見逃す場合があるため、アプリケーション開発者が登録を行う必要があります。これには 2 つの方法があります。
@io.quarkus.runtime.annotations.RegisterForReflection
アノテーションを使用して、使用するクラスを登録できます。targets
属性を使用してサードパーティークラスを登録することもできます。import io.quarkus.runtime.annotations.RegisterForReflection; @RegisterForReflection class MyClassAccessedReflectively { } @RegisterForReflection( targets = { org.third-party.Class1.class, org.third-party.Class2.class } ) class ReflectionRegistrations { }
import io.quarkus.runtime.annotations.RegisterForReflection; @RegisterForReflection class MyClassAccessedReflectively { } @RegisterForReflection( targets = { org.third-party.Class1.class, org.third-party.Class2.class } ) class ReflectionRegistrations { }
Copy to Clipboard Copied! 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
quarkus.camel.native.reflection.include-patterns = org.apache.commons.lang3.tuple.* quarkus.camel.native.reflection.exclude-patterns = org.apache.commons.lang3.tuple.*Triple
Copy to Clipboard Copied! このオプションが適切に機能するには、選択したクラスが含まれるアーティファクトに 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
quarkus.index-dependency.commons-lang3.group-id = org.apache.commons quarkus.index-dependency.commons-lang3.artifact-id = commons-lang3
Copy to Clipboard Copied!
8.6. シリアル化のためのクラスの登録
quarkus.camel.native.reflection.serialization-enabled
を介してシリアル化サポートが要求されると、CamelSerializationProcessor.BASE_SERIALIZATION_CLASSES に一覧表示されているクラスは、シリアル化のために自動的に登録されます。
@RegisterForReflection(serialization = true)
を使用してさらに多くのクラスを登録できます。
第9章 Kubernetes
このガイドでは、Kubernetes 上で Camel Quarkus アプリケーションを設定およびデプロイするさまざまな方法を説明します。また、Knative と Service Binding の具体的な使用例も説明します。
9.1. Kubernetes
Quarkus は、vanilla Kubernetes、OpenShift、Knative のリソースの生成をサポートしています。さらに、Quarkus は、生成されたマニフェストをターゲットクラスターの API サーバーに適用することで、アプリケーションをターゲット Kubernetes クラスターにデプロイできます。詳細は、Quarkus Kubernetes ガイド
を参照してください。
9.2. Knative
Knative デプロイメントをサポートする Camel Quarkus 拡張機能は次のとおりです。
9.3. サービスバインディング
Quarkus は、サービスをアプリケーションにバインドするための Service Binding Specification for Kubernetes をサポートします。
次の Camel Quarkus 拡張機能は、Service Binding で使用できます。
第10章 Quarkus CXF セキュリティーガイド
この章では、Quarkus CXF エクステンションを使用する際のセキュリティーに関する情報を提供します。
10.1. セキュリティーガイド
セキュリティーガイドには、Quarkus CXF のセキュリティーに関連するさまざまな側面が記載されています。
10.1.1. SSL、TLS、および HTTPS
このセクションでは、SSL、TLS、HTTPS に関連するさまざまなユースケースを説明します。
このセクションで使用されているサンプルコードは、Quarkus CXF のソースツリーにある WS-WS-SecurityPolicy integration test からの抜粋です。
10.1.1.1. クライアント SSL 設定
クライアントが、クライアントのオペレーティングシステムによって SSL 証明書が信頼されていないサーバーと通信する場合は、クライアント用にカスタムトラストストアを設定する必要があります。
トラストストアの作成と維持には、openssl
や Java keytool
などのツールがよく使用されます。
Quarkus CXF ソースツリーには、両方のツールの例があります。
トラストストアを準備したら、それを使用するようにクライアントを設定する必要があります。
10.1.1.1.1. application.properties
にクライアントトラストストアを設定する
これは、最も簡単にクライアントトラストストアを設定できる方法です。次のプロパティーには、重要な役割があります。
以下に例を示します。
application.properties
Client side SSL
# Client side SSL
quarkus.cxf.client.hello.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/hello
quarkus.cxf.client.hello.service-interface = io.quarkiverse.cxf.it.security.policy.HelloService
quarkus.cxf.client.hello.trust-store-type = pkcs12
quarkus.cxf.client.hello.trust-store = client-truststore.pkcs12
quarkus.cxf.client.hello.trust-store-password = client-truststore-password
- 1
pkcs12
とjks
は、よく使用される 2 つのキーストア形式です。PKCS12 は、Java 9 以降の デフォルトの Java キーストア形式 です。PKCS12 はより強力な暗号化アルゴリズムを提供し、拡張可能で、標準化されており、言語に中立で、広くサポートされているため、JKS ではなく PKCS12 を使用することを推奨します。- 2
- 参照される
client-truststore.pkcs12
ファイルは、クラスパスまたはファイルシステムのいずれかで使用可能である必要があります。
10.1.1.2. サーバー SSL 設定
HTTPS プロトコル経由でサービスを利用できるようにするには、まずサーバーキーストアを設定する必要があります。サーバーの SSL 設定は、Quarkus の HTTP レイヤーである Vert.x によって実行されます。Quarkus HTTP ガイド では、設定オプションに関する情報が提供されています。
以下に基本的な例を示します。
application.properties
Server side SSL
# Server side SSL
quarkus.tls.key-store.p12.path = localhost-keystore.pkcs12
quarkus.tls.key-store.p12.password = localhost-keystore-password
quarkus.tls.key-store.p12.alias = localhost
quarkus.tls.key-store.p12.alias-password = localhost-keystore-password
10.1.1.3. 相互 TLS (mTLS) 認証
これまでは、サーバーのみが SSL 証明書を通じてアイデンティティーを証明し、クライアントがその証明書を信頼するように設定する必要がある単純なケース、つまり片側だけのケースを説明しました。相互 TLS 認証では、クライアントにも同じ公開鍵暗号化手段を使用してアイデンティティーを証明させます。
したがって、相互 TLS (mTLS) 認証の場合、上記のようにサーバーキーストアとクライアントトラストストアをセットアップすることに加えて、クライアント側のキーストアとサーバー側のトラストストアをセットアップする必要があります。
ストアを作成および維持するためのツールは同じであり、使用する設定プロパティーは Simple TLS の場合に使用されるものとほぼ類似しています。
Quarkus CXF ソースツリーの mTLS インテグレーションテスト は、適切なスタートポイントになります。
キーストアとトラストストアは、openssl
(または Java Java keytool
) を使用して作成されます。
application.properties
ファイルは次のとおりです。
application.properties
Server keystore for Simple TLS Server truststore for Mutual TLS Select localhost-pkcs12 as the TLS configuration for the HTTP server Do not allow any clients which do not prove their indentity through an SSL certificate CXF service CXF client with a properly set certificate for mTLS Include the keystores in the native executable
# Server keystore for Simple TLS
quarkus.tls.localhost-pkcs12.key-store.p12.path = localhost-keystore.pkcs12
quarkus.tls.localhost-pkcs12.key-store.p12.password = localhost-keystore-password
quarkus.tls.localhost-pkcs12.key-store.p12.alias = localhost
quarkus.tls.localhost-pkcs12.key-store.p12.alias-password = localhost-keystore-password
# Server truststore for Mutual TLS
quarkus.tls.localhost-pkcs12.trust-store.p12.path = localhost-truststore.pkcs12
quarkus.tls.localhost-pkcs12.trust-store.p12.password = localhost-truststore-password
# Select localhost-pkcs12 as the TLS configuration for the HTTP server
quarkus.http.tls-configuration-name = localhost-pkcs12
# Do not allow any clients which do not prove their indentity through an SSL certificate
quarkus.http.ssl.client-auth = required
# CXF service
quarkus.cxf.endpoint."/mTls".implementor = io.quarkiverse.cxf.it.auth.mtls.MTlsHelloServiceImpl
# CXF client with a properly set certificate for mTLS
quarkus.cxf.client.mTls.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/mTls
quarkus.cxf.client.mTls.service-interface = io.quarkiverse.cxf.it.security.policy.HelloService
quarkus.cxf.client.mTls.key-store = target/classes/client-keystore.pkcs12
quarkus.cxf.client.mTls.key-store-type = pkcs12
quarkus.cxf.client.mTls.key-store-password = client-keystore-password
quarkus.cxf.client.mTls.key-password = client-keystore-password
quarkus.cxf.client.mTls.trust-store = target/classes/client-truststore.pkcs12
quarkus.cxf.client.mTls.trust-store-type = pkcs12
quarkus.cxf.client.mTls.trust-store-password = client-truststore-password
# Include the keystores in the native executable
quarkus.native.resources.includes = *.pkcs12,*.jks
10.1.1.4. WS-SecurityPolicy を通じて SSL を強制する
クライアントが HTTPS 経由で接続するための要件は、ポリシーで定義できます。
この機能は、quarkus-cxf-rt-ws-security
エクステンションにより提供されます。
以下は、ポリシーファイルの例です。
https-policy.xml
<?xml version="1.0" encoding="UTF-8"?> <wsp:Policy wsp:Id="HttpsSecurityServicePolicy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <wsp:ExactlyOne> <wsp:All> <sp:TransportBinding> <wsp:Policy> <sp:TransportToken> <wsp:Policy> <sp:HttpsToken RequireClientCertificate="false" /> </wsp:Policy> </sp:TransportToken> <sp:IncludeTimestamp /> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic128 /> </wsp:Policy> </sp:AlgorithmSuite> </wsp:Policy> </sp:TransportBinding> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy wsp:Id="HttpsSecurityServicePolicy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding>
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false" />
</wsp:Policy>
</sp:TransportToken>
<sp:IncludeTimestamp />
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128 />
</wsp:Policy>
</sp:AlgorithmSuite>
</wsp:Policy>
</sp:TransportBinding>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
ポリシーは、サービスエンドポイントインターフェイス (SEI) から参照される必要があります。
HttpsPolicyHelloService.java
package io.quarkiverse.cxf.it.security.policy; import jakarta.jws.WebMethod; import jakarta.jws.WebService; import org.apache.cxf.annotations.Policy; /** * A service implementation with a transport policy set */ @WebService(serviceName = "HttpsPolicyHelloService") @Policy(placement = Policy.Placement.BINDING, uri = "https-policy.xml") public interface HttpsPolicyHelloService extends AbstractHelloService { @WebMethod @Override public String hello(String text); }
package io.quarkiverse.cxf.it.security.policy;
import jakarta.jws.WebMethod;
import jakarta.jws.WebService;
import org.apache.cxf.annotations.Policy;
/**
* A service implementation with a transport policy set
*/
@WebService(serviceName = "HttpsPolicyHelloService")
@Policy(placement = Policy.Placement.BINDING, uri = "https-policy.xml")
public interface HttpsPolicyHelloService extends AbstractHelloService {
@WebMethod
@Override
public String hello(String text);
}
このセットアップを行うと、HTTP 経由で配信されるすべてのリクエストは PolicyVerificationInInterceptor
によって拒否されます。
ERROR [org.apa.cxf.ws.pol.PolicyVerificationInInterceptor] Inbound policy verification failed: These policy alternatives can not be satisfied: {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding: TLS is not enabled ...
ERROR [org.apa.cxf.ws.pol.PolicyVerificationInInterceptor] Inbound policy verification failed: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding: TLS is not enabled
...
10.1.2. 認証および認可
このセクションに示されているサンプルコードは、Quarkus CXF のソースツリーにある Client and server integration test からの抜粋です。これは、実行可能な例として使用できます。
10.1.2.1. クライアント HTTP Basic 認証
quarkus-cxf
エクステンションによって提供される次のクライアント設定オプションを使用して、HTTP Basic 認証のユーザー名とパスワードを渡します。
以下に例を示します。
application.properties
quarkus.cxf.client.basicAuth.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl quarkus.cxf.client.basicAuth.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuth quarkus.cxf.client.basicAuth.username = bob quarkus.cxf.client.basicAuth.password = bob234
quarkus.cxf.client.basicAuth.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuth.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuth
quarkus.cxf.client.basicAuth.username = bob
quarkus.cxf.client.basicAuth.password = bob234
10.1.2.1.1. Basic 認証で保護された WSDL へのアクセス
デフォルトでは、quarkus.cxf.client."client-name".secure-wsdl-access
を true
に設定しない限り、Quarkus CXF によって作成されたクライアントは Authorization
ヘッダーを送信しません。
application.properties
quarkus.cxf.client.basicAuthSecureWsdl.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl quarkus.cxf.client.basicAuthSecureWsdl.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuthSecureWsdl quarkus.cxf.client.basicAuthSecureWsdl.username = bob quarkus.cxf.client.basicAuthSecureWsdl.password = ${client-server.bob.password} quarkus.cxf.client.basicAuthSecureWsdl.secure-wsdl-access = true
quarkus.cxf.client.basicAuthSecureWsdl.wsdl = http://localhost:${quarkus.http.test-port}/soap/basicAuth?wsdl
quarkus.cxf.client.basicAuthSecureWsdl.client-endpoint-url = http://localhost:${quarkus.http.test-port}/soap/basicAuthSecureWsdl
quarkus.cxf.client.basicAuthSecureWsdl.username = bob
quarkus.cxf.client.basicAuthSecureWsdl.password = ${client-server.bob.password}
quarkus.cxf.client.basicAuthSecureWsdl.secure-wsdl-access = true
10.1.2.2. 相互 TLS (mTLS) 認証
SSL、TLS、HTTPS ガイドの 相互 TLS (mTLS) 認証 セクションを参照してください。
10.1.2.3. サービスエンドポイントの保護
特に以下の点において、サーバー側の認証と認可は Quarkus Security によって実行されます。
具体的な例は、Client and server integration test を参照してください。主に以下が含まれます。
-
アイデンティティープロバイダーとしての
io.quarkus:quarkus-elytron-security-properties-file
依存関係 Basic 認証の有効化と、
application.properties
でロールが設定されているユーザー。application.properties
quarkus.http.auth.basic = true quarkus.security.users.embedded.enabled = true quarkus.security.users.embedded.plain-text = true quarkus.security.users.embedded.users.alice = alice123 quarkus.security.users.embedded.roles.alice = admin quarkus.security.users.embedded.users.bob = bob234 quarkus.security.users.embedded.roles.bob = app-user
quarkus.http.auth.basic = true quarkus.security.users.embedded.enabled = true quarkus.security.users.embedded.plain-text = true quarkus.security.users.embedded.users.alice = alice123 quarkus.security.users.embedded.roles.alice = admin quarkus.security.users.embedded.users.bob = bob234 quarkus.security.users.embedded.roles.bob = app-user
Copy to Clipboard Copied! -
@RolesAllowed
アノテーションによって強制されるロールベースのアクセス制御。
BasicAuthHelloServiceImpl.java
package io.quarkiverse.cxf.it.auth.basic; import jakarta.annotation.security.RolesAllowed; import jakarta.jws.WebService; import io.quarkiverse.cxf.it.HelloService; @WebService(serviceName = "HelloService", targetNamespace = HelloService.NS) @RolesAllowed("app-user") public class BasicAuthHelloServiceImpl implements HelloService { @Override public String hello(String person) { return "Hello " + person + "!"; } }
package io.quarkiverse.cxf.it.auth.basic;
import jakarta.annotation.security.RolesAllowed;
import jakarta.jws.WebService;
import io.quarkiverse.cxf.it.HelloService;
@WebService(serviceName = "HelloService", targetNamespace = HelloService.NS)
@RolesAllowed("app-user")
public class BasicAuthHelloServiceImpl implements HelloService {
@Override
public String hello(String person) {
return "Hello " + person + "!";
}
}
10.1.3. WS-SecurityPolicy によって強制される認証
クライアント と サービス に対して、相互 TLS と Basic HTTP 認証の代わりに、WS-SecurityPolicy を通じて認証を強制できます。
WS-SecurityPolicy を通じて認証を強制するには、次の手順に従います。
- WSDL コントラクトのエンドポイントにサポートトークンポリシーを追加します。
-
サーバー側では、認証コールバックハンドラーを実装し、
application.properties
または環境変数を介してエンドポイントに関連付けます。クライアントから受信した認証情報は、コールバックハンドラーによって認証されます。 -
クライアント側では、
application.properties
内の設定または環境変数を通じて認証情報を提供します。または、認証コールバックハンドラーを実装して認証情報を渡すこともできます。
10.1.3.1. 認証ポリシーの指定
サービスエンドポイントで認証を強制する場合は、サポートトークン ポリシーアサーションを関連するエンドポイントバインディングに関連付け、その下に 1 つ以上の トークンアサーション を指定します。
サポートトークンポリシーアサーションにはいくつかの種類があり、その XML 要素名はすべて SupportingTokens
で終わります (たとえば、SupportingTokens
、SignedSupportingTokens
など)。完全なリストは、WS-SecurityPolicy 仕様の Supporting Tokens のセクションを参照してください。
10.1.3.2. UsernameToken
ポリシーアサーションの例
このセクションで使用されるサンプルコードスニペットは、Quarkus CXF のソースツリーにある WS-SecurityPolicy インテグレーションテスト からのものです。これは、実行可能な例として使用できます。
次のリストは、WS-Security UsernameToken
(ユーザー名/パスワードの認証情報を含む) をセキュリティーヘッダーに含めることを要求するポリシーの例を示しています。
username-token-policy.xml
<?xml version="1.0" encoding="UTF-8"?> <wsp:Policy wsp:Id="UsernameTokenSecurityServicePolicy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <wsp:ExactlyOne> <wsp:All> <sp:SupportingTokens> <wsp:Policy> <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:WssUsernameToken11 /> <sp13:Created /> <sp13:Nonce /> </wsp:Policy> </sp:UsernameToken> </wsp:Policy> </sp:SupportingTokens> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy
wsp:Id="UsernameTokenSecurityServicePolicy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken11 />
<sp13:Created />
<sp13:Nonce />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
このポリシーファイルをサービスエンドポイントに関連付けるには、次の 2 つの方法があります。
次のように、サービスエンドポイントインターフェイス (SEI) のポリシーを参照します。
UsernameTokenPolicyHelloService.java
@WebService(serviceName = "UsernameTokenPolicyHelloService") @Policy(placement = Policy.Placement.BINDING, uri = "username-token-policy.xml") public interface UsernameTokenPolicyHelloService extends AbstractHelloService { ... }
@WebService(serviceName = "UsernameTokenPolicyHelloService") @Policy(placement = Policy.Placement.BINDING, uri = "username-token-policy.xml") public interface UsernameTokenPolicyHelloService extends AbstractHelloService { ... }
Copy to Clipboard Copied! -
WSDL 契約に ポリシーを含め、
PolicyReference
要素 を介して参照します。
ポリシーを設定したら、サービスエンドポイントとクライアントで認証情報を設定します。
application.properties
A service with a UsernameToken policy assertion These properties are used in UsernameTokenPasswordCallback and in the configuration of the helloUsernameToken below A client with a UsernameToken policy assertion
# A service with a UsernameToken policy assertion
quarkus.cxf.endpoint."/helloUsernameToken".implementor = io.quarkiverse.cxf.it.security.policy.UsernameTokenPolicyHelloServiceImpl
quarkus.cxf.endpoint."/helloUsernameToken".security.callback-handler = #usernameTokenPasswordCallback
# These properties are used in UsernameTokenPasswordCallback
# and in the configuration of the helloUsernameToken below
wss.user = cxf-user
wss.password = secret
# A client with a UsernameToken policy assertion
quarkus.cxf.client.helloUsernameToken.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/helloUsernameToken
quarkus.cxf.client.helloUsernameToken.service-interface = io.quarkiverse.cxf.it.security.policy.UsernameTokenPolicyHelloService
quarkus.cxf.client.helloUsernameToken.security.username = ${wss.user}
quarkus.cxf.client.helloUsernameToken.security.password = ${wss.password}
上記のリストでは、usernameTokenPasswordCallback
は、javax.security.auth.callback.CallbackHandler
を実装する @jakarta.inject.Named
Bean の名前です。Quarkus CXF は、CDI コンテナー内でこの 名前 の Bean を検索します。
以下は Bean の実装例です。
UsernameTokenPasswordCallback.java
package io.quarkiverse.cxf.it.security.policy; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Named; import org.apache.wss4j.common.ext.WSPasswordCallback; import org.eclipse.microprofile.config.inject.ConfigProperty; @ApplicationScoped @Named("usernameTokenPasswordCallback") /* We refer to this bean by this name from application.properties */ public class UsernameTokenPasswordCallback implements CallbackHandler { /* These two configuration properties are set in application.properties */ @ConfigProperty(name = "wss.password") String password; @ConfigProperty(name = "wss.user") String user; @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { if (callbacks.length < 1) { throw new IllegalStateException("Expected a " + WSPasswordCallback.class.getName() + " at possition 0 of callbacks. Got array of length " + callbacks.length); } if (!(callbacks[0] instanceof WSPasswordCallback)) { throw new IllegalStateException( "Expected a " + WSPasswordCallback.class.getName() + " at possition 0 of callbacks. Got an instance of " + callbacks[0].getClass().getName() + " at possition 0"); } final WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; if (user.equals(pc.getIdentifier())) { pc.setPassword(password); } else { throw new IllegalStateException("Unexpected user " + user); } } }
package io.quarkiverse.cxf.it.security.policy;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@ApplicationScoped
@Named("usernameTokenPasswordCallback") /* We refer to this bean by this name from application.properties */
public class UsernameTokenPasswordCallback implements CallbackHandler {
/* These two configuration properties are set in application.properties */
@ConfigProperty(name = "wss.password")
String password;
@ConfigProperty(name = "wss.user")
String user;
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
if (callbacks.length < 1) {
throw new IllegalStateException("Expected a " + WSPasswordCallback.class.getName()
+ " at possition 0 of callbacks. Got array of length " + callbacks.length);
}
if (!(callbacks[0] instanceof WSPasswordCallback)) {
throw new IllegalStateException(
"Expected a " + WSPasswordCallback.class.getName() + " at possition 0 of callbacks. Got an instance of "
+ callbacks[0].getClass().getName() + " at possition 0");
}
final WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if (user.equals(pc.getIdentifier())) {
pc.setPassword(password);
} else {
throw new IllegalStateException("Unexpected user " + user);
}
}
}
セットアップ全体をテストするには、単純な @QuarkusTest
を作成します。
UsernameTokenTest.java
package io.quarkiverse.cxf.it.security.policy; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import io.quarkiverse.cxf.annotation.CXFClient; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest public class UsernameTokenTest { @CXFClient("helloUsernameToken") UsernameTokenPolicyHelloService helloUsernameToken; @Test void helloUsernameToken() { Assertions.assertThat(helloUsernameToken.hello("CXF")).isEqualTo("Hello CXF from UsernameToken!"); } }
package io.quarkiverse.cxf.it.security.policy;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import io.quarkiverse.cxf.annotation.CXFClient;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
public class UsernameTokenTest {
@CXFClient("helloUsernameToken")
UsernameTokenPolicyHelloService helloUsernameToken;
@Test
void helloUsernameToken() {
Assertions.assertThat(helloUsernameToken.hello("CXF")).isEqualTo("Hello CXF from UsernameToken!");
}
}
mvn test -Dtest=UsernameTokenTest
でテストを実行すると、Username
と Password
を含む Security
ヘッダーを含む SOAP メッセージがログに記録されます。
UsernameTokenTest のログ出力
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-bac4f255-147e-42a4-aeec-e0a3f5cd3587"> <wsse:Username>cxf-user</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">secret</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">3uX15dZT08jRWFWxyWmfhg==</wsse:Nonce> <wsu:Created>2024-10-02T17:32:10.497Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <ns2:hello xmlns:ns2="http://policy.security.it.cxf.quarkiverse.io/"> <arg0>CXF</arg0> </ns2:hello> </soap:Body> </soap:Envelope>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-bac4f255-147e-42a4-aeec-e0a3f5cd3587">
<wsse:Username>cxf-user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">secret</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">3uX15dZT08jRWFWxyWmfhg==</wsse:Nonce>
<wsu:Created>2024-10-02T17:32:10.497Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<ns2:hello xmlns:ns2="http://policy.security.it.cxf.quarkiverse.io/">
<arg0>CXF</arg0>
</ns2:hello>
</soap:Body>
</soap:Envelope>
10.1.3.3. SAML v1 および v2 ポリシーアサーションの例
WS-SecurityPolicy インテグレーションテスト には、SAML v1 および SAML v2 アサーションを使用した類似の例も含まれています。
第11章 Camel のセキュリティー
この章では、Camel ルートのセキュリティーオプションを説明します。
11.1. Camel セキュリティーの概要
Camel は、Camel ルートで利用できるさまざまな形式およびレベルのセキュリティー機能を提供します。これらのさまざまな形式のセキュリティーは、相互に組み合わせて使用することも、個別に使用することもできます。
提供される大まかなカテゴリーは次のとおりです。
- ルートセキュリティー - ルートまたはルートセグメントを続行するための認証および認可サービス
- ペイロードセキュリティー - ペイロードレベルで暗号化/復号化サービスを提供するデータ形式
- エンドポイントセキュリティー - コンポーネントに関連付けられた endpointUri で利用できるコンポーネントによって提供されるセキュリティー
- 設定セキュリティー - 設定ファイルまたは外部の Secured Vault システムからの機密情報を暗号化することで提供されるセキュリティー。
Camel は、多数の Camel コンポーネントの SSL/TLS 関連の側面を設定するための JSSE ユーティリティー を提供します。
11.2. ルートセキュリティー
認証および認可サービス
Camel は、ルートまたはルートセグメントに組み込むことができる ルートポリシー 駆動型のセキュリティー機能を提供します。Camel のルートポリシーは、Camel プロセッサーにインターセプターを適用するためのストラテジーパターンを利用します。Camel ルートの横断的な懸念事項 (セキュリティー、トランザクションなど) を適用する機能を提供します。
11.3. ペイロードセキュリティー
Camel は、ペイロードを保護したり、ペイロードの一部/セクションに暗号化/復号化機能を選択的に適用したりするための暗号化/復号化サービスを提供します。
Marshal を利用してペイロードの暗号化/復号を提供するデータ形式は次のとおりです。
11.4. エンドポイントセキュリティー
Camel の一部のコンポーネントは、エンドポイントを保護する機能 (インターセプターなどを使用) を提供しているため、それによりペイロードの保護や、コンポーネントを使用して作成されたエンドポイントでの認証および認可機能を実現する能力を備えています。
11.5. 設定セキュリティー
Camel は、設定値をプロパティーファイルに外部化するための Properties コンポーネントを提供します。これらの値には、ユーザー名やパスワードなどの機密情報が含まれている可能性があります。
これらの値は、Camel によって以下を使用して暗号化および自動的に復号化できます。
Camel は、外部の Vault システムからの保護された設定へのアクセスもサポートします。
11.5.1. Vault を使用した設定セキュリティー
Camel では次の Vault がサポートされています。
11.5.1.1. AWS Vault の使用
AWS Secrets Manager を使用するには、accessKey、secretKey、および リージョン を指定する必要があります。これは、アプリケーションを起動する前に環境変数を使用して実行できます。
export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey
export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey
export $CAMEL_VAULT_AWS_REGION=region
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.aws.accessKey = accessKey camel.vault.aws.secretKey = secretKey camel.vault.aws.region = region
camel.vault.aws.accessKey = accessKey
camel.vault.aws.secretKey = secretKey
camel.vault.aws.region = region
代わりに AWS のデフォルトの認証情報プロバイダー を使用する場合は、次の環境変数を指定する必要があります。
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true
export $CAMEL_VAULT_AWS_REGION=region
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.aws.defaultCredentialsProvider = true camel.vault.aws.region = region
camel.vault.aws.defaultCredentialsProvider = true
camel.vault.aws.region = region
AWS Secrets Manager にアクセスするための特定のプロファイル名を指定することもできます。
export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true
export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account
export $CAMEL_VAULT_AWS_REGION=region
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.aws.profileCredentialsProvider = true camel.vault.aws.profileName = test-account camel.vault.aws.region = region
camel.vault.aws.profileCredentialsProvider = true
camel.vault.aws.profileName = test-account
camel.vault.aws.region = region
この時点で、{{ }}
構文で aws:
を接頭辞として使用して、次のようにプロパティーを参照できるようになります。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{aws:route}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{aws:route}}"/>
</route>
</camelContext>
ここで、route
は、AWS Secrets Manager Service に保存されているシークレットの名前になります。
AWS Secret Manager にシークレットが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{aws:route:default}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{aws:route:default}}"/>
</route>
</camelContext>
この場合、シークレットが存在しない場合は、プロパティーの値は "default" にフォールバックします。
また、たとえば次の形式の database という名前のシークレットがある場合、シークレットの特定のフィールドを取得できます。
{ "username": "admin", "password": "password123", "engine": "postgres", "host": "127.0.0.1", "port": "3128", "dbname": "db" }
{
"username": "admin",
"password": "password123",
"engine": "postgres",
"host": "127.0.0.1",
"port": "3128",
"dbname": "db"
}
たとえば次のように、ルート内で単一のシークレット値を取得できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{aws:database/username}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{aws:database/username}}"/>
</route>
</camelContext>
または、エンドポイントの一部としてプロパティーを再利用します。
AWS Secret Manager に特定のシークレットフィールドが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{aws:database/username:admin}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{aws:database/username:admin}}"/>
</route>
</camelContext>
この場合、シークレットが存在しないか、シークレットは存在するがユーザー名フィールドがシークレットの一部ではない場合、プロパティーは値として "admin" にフォールバックします。
現時点では、回転機能は (適用される場合があるとしても) 考慮していませんが、作業項目の一部に含まれています。
唯一の要件は、Camel アプリケーションに camel-aws-secrets-manager
JAR を追加することです。
11.5.1.2. Google Secret Manager GCP Vault の使用
GCP Secret Manager を使用するには、serviceAccountKey ファイルと GCP projectId を提供する必要があります。これは、アプリケーションを起動する前に環境変数を使用して実行できます。
export $CAMEL_VAULT_GCP_SERVICE_ACCOUNT_KEY=file:////path/to/service.accountkey export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_SERVICE_ACCOUNT_KEY=file:////path/to/service.accountkey
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.gcp.serviceAccountKey = accessKey camel.vault.gcp.projectId = secretKey
camel.vault.gcp.serviceAccountKey = accessKey
camel.vault.gcp.projectId = secretKey
代わりに GCP のデフォルトのクライアントインスタンス を使用する場合は、次の環境変数を指定する必要があります。
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.gcp.useDefaultInstance = true camel.vault.aws.projectId = region
camel.vault.gcp.useDefaultInstance = true
camel.vault.aws.projectId = region
この時点で、{{ }}
構文で gcp:
を接頭辞として使用することで、次のようにプロパティーを参照できるようになります。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{gcp:route}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{gcp:route}}"/>
</route>
</camelContext>
ここで、route
は GCP Secret Manager サービスに保存されているシークレットの名前になります。
GCP Secret Manager にシークレットが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{gcp:route:default}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{gcp:route:default}}"/>
</route>
</camelContext>
この場合、シークレットが存在しない場合は、プロパティーの値は "default" にフォールバックします。
また、たとえば次の形式の database という名前のシークレットがある場合、シークレットの特定のフィールドを取得できます。
{ "username": "admin", "password": "password123", "engine": "postgres", "host": "127.0.0.1", "port": "3128", "dbname": "db" }
{
"username": "admin",
"password": "password123",
"engine": "postgres",
"host": "127.0.0.1",
"port": "3128",
"dbname": "db"
}
たとえば次のように、ルート内で単一のシークレット値を取得できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{gcp:database/username}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{gcp:database/username}}"/>
</route>
</camelContext>
または、エンドポイントの一部としてプロパティーを再利用します。
GCP Secret Manager に特定のシークレットフィールドが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{gcp:database/username:admin}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{gcp:database/username:admin}}"/>
</route>
</camelContext>
この場合、シークレットが存在しないか、シークレットは存在するがユーザー名フィールドがシークレットの一部ではない場合、プロパティーは値として "admin" にフォールバックします。
現時点では、回転機能は (適用される場合があるとしても) 考慮していませんが、作業項目の一部に含まれています。
要件は 2 つだけです: - Camel アプリケーションに camel-google-secret-manager
JAR を追加します。- サービスアカウントに、シークレット管理レベルで操作を行うための権限を付与します (たとえば、シークレットペイロードにアクセスする、シークレットマネージャーサービスの管理者になるなど)。
11.5.1.3. Azure Key Vault の使用
この機能を使用するには、環境変数として Azure Key Vault サービスに認証情報を提供する必要があります。
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.azure.tenantId = accessKey camel.vault.azure.clientId = clientId camel.vault.azure.clientSecret = clientSecret camel.vault.azure.vaultName = vaultName
camel.vault.azure.tenantId = accessKey
camel.vault.azure.clientId = clientId
camel.vault.azure.clientSecret = clientSecret
camel.vault.azure.vaultName = vaultName
または、次の方法で Azure Identity の使用を有効にすることもできます。
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
次のように、application.properties
ファイルで Azure アイデンティティーの使用を有効にすることもできます。
camel.vault.azure.azureIdentityEnabled = true camel.vault.azure.vaultName = vaultName
camel.vault.azure.azureIdentityEnabled = true
camel.vault.azure.vaultName = vaultName
この時点で、次の方法でプロパティーを参照できるようになります。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{azure:route}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{azure:route}}"/>
</route>
</camelContext>
ここで、route は Azure Key Vault サービスに保存されているシークレットの名前になります。
Azure Key Vault サービスにシークレットが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{azure:route:default}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{azure:route:default}}"/>
</route>
</camelContext>
この場合、シークレットが存在しない場合は、プロパティーの値は "default" にフォールバックします。
また、たとえば次の形式の database という名前のシークレットがある場合、シークレットの特定のフィールドを取得することもできます。
{ "username": "admin", "password": "password123", "engine": "postgres", "host": "127.0.0.1", "port": "3128", "dbname": "db" }
{
"username": "admin",
"password": "password123",
"engine": "postgres",
"host": "127.0.0.1",
"port": "3128",
"dbname": "db"
}
たとえば次のように、ルート内で単一のシークレット値を取得できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{azure:database/username}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{azure:database/username}}"/>
</route>
</camelContext>
または、エンドポイントの一部としてプロパティーを再利用します。
特定のシークレットフィールドが Azure Key Vault に存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{azure:database/username:admin}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{azure:database/username:admin}}"/>
</route>
</camelContext>
この場合、シークレットが存在しないか、シークレットは存在するがユーザー名フィールドがシークレットの一部ではない場合、プロパティーは値として "admin" にフォールバックします。
現時点では、回転機能は (適用される場合があるとしても) 考慮していませんが、作業項目の一部に含まれています。
唯一の要件は、Camel アプリケーションに camel-azure-key-vault jar を追加することです。
11.5.1.4. Hashicorp Vault の使用
この機能を使用するには、環境変数として Hashicorp vault の認証情報を提供する必要があります。
export $CAMEL_VAULT_HASHICORP_TOKEN=token export $CAMEL_VAULT_HASHICORP_HOST=host export $CAMEL_VAULT_HASHICORP_PORT=port export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
export $CAMEL_VAULT_HASHICORP_TOKEN=token
export $CAMEL_VAULT_HASHICORP_HOST=host
export $CAMEL_VAULT_HASHICORP_PORT=port
export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
次のように、application.properties
ファイルで認証情報を設定することもできます。
camel.vault.hashicorp.token = token camel.vault.hashicorp.host = host camel.vault.hashicorp.port = port camel.vault.hashicorp.scheme = scheme
camel.vault.hashicorp.token = token
camel.vault.hashicorp.host = host
camel.vault.hashicorp.port = port
camel.vault.hashicorp.scheme = scheme
この時点で、次の方法でプロパティーを参照できるようになります。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{hashicorp:secret:route}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{hashicorp:secret:route}}"/>
</route>
</camelContext>
ここで、route は、Hashicorp Vault インスタンスの 'secret' エンジンに保存されているシークレットの名前になります。
Hashicorp Vault インスタンスにシークレットが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{hashicorp:secret:route:default}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{hashicorp:secret:route:default}}"/>
</route>
</camelContext>
この場合、シークレットが 'secret' エンジンに存在しない場合は、プロパティーの値は "default" に戻ります。
また、たとえば次の形式の database という名前のシークレットがある場合、シークレットの特定のフィールドを取得できます。
{ "username": "admin", "password": "password123", "engine": "postgres", "host": "127.0.0.1", "port": "3128", "dbname": "db" }
{
"username": "admin",
"password": "password123",
"engine": "postgres",
"host": "127.0.0.1",
"port": "3128",
"dbname": "db"
}
たとえば次のように、ルート内の 'secret' エンジンで単一のシークレット値を取得できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{hashicorp:secret:database/username}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{hashicorp:secret:database/username}}"/>
</route>
</camelContext>
または、エンドポイントの一部としてプロパティーを再利用します。
Hashicorp Vault インスタンスの 'secret' エンジンに、特定の secret フィールドが存在しない場合は、デフォルト値を指定できます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{hashicorp:secret:database/username:admin}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{hashicorp:secret:database/username:admin}}"/>
</route>
</camelContext>
この場合、シークレットが存在しないか、シークレットが存在する ('secret' エンジン内) がユーザー名フィールドがシークレットの一部ではない場合、プロパティーの値は "admin" にフォールバックされます。
フィールド/デフォルト値を指定して、またはシークレットのみを使用して、両方のアプローチでシークレットの特定のバージョンを取得するための構文もあります。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{hashicorp:secret:route@2}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{hashicorp:secret:route@2}}"/>
</route>
</camelContext>
このアプローチでは、'secret' エンジンでバージョン '2' の RAW ルートシークレットが返されます。
<camelContext> <route> <from uri="direct:start"/> <to uri="{{hashicorp:route:default@2}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<to uri="{{hashicorp:route:default@2}}"/>
</route>
</camelContext>
このアプローチでは、('secret' エンジン内に) シークレットが存在しない場合、またはバージョンが存在しない場合、バージョン '2' またはデフォルト値のルートシークレット値が返されます。
<camelContext> <route> <from uri="direct:start"/> <log message="Username is {{hashicorp:secret:database/username:admin@2}}"/> </route> </camelContext>
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{hashicorp:secret:database/username:admin@2}}"/>
</route>
</camelContext>
このアプローチでは、データベースシークレットのユーザー名フィールドがバージョン '2' で返されます。あるいは、('secret' エンジン内) にシークレットが存在しない場合、またはバージョンが存在しない場合は、admin が返されます。
11.5.1.5. AWS Secrets Manager 使用時の Secret Refresh での Camel コンテキストの自動リロード
シークレットの更新時に Camel コンテキストをリロードできるようにするには、通常の認証情報 (AWS Secret Manager Property 関数で使用されるものと同じ) を指定します。
環境変数を使用する場合:
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=accessKey export $CAMEL_VAULT_AWS_REGION=region
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=accessKey
export $CAMEL_VAULT_AWS_REGION=region
または単純な Camel のメインプロパティーとしての場合:
camel.vault.aws.useDefaultCredentialProvider = true camel.vault.aws.region = region
camel.vault.aws.useDefaultCredentialProvider = true
camel.vault.aws.region = region
または、デフォルトの認証情報プロバイダーチェーンを使用する代わりに、accessKey/SecretKey とリージョンを指定します。
自動更新を有効にするには、追加のプロパティーを設定する必要があります。
camel.vault.aws.refreshEnabled=true camel.vault.aws.refreshPeriod=60000 camel.vault.aws.secrets=Secret camel.main.context-reload-enabled = true
camel.vault.aws.refreshEnabled=true
camel.vault.aws.refreshPeriod=60000
camel.vault.aws.secrets=Secret
camel.main.context-reload-enabled = true
ここで、camel.vault.aws.refreshEnabled
は、自動コンテキストリロードを有効にし、camel.vault.aws.refreshPeriod
は更新イベントの 2 つの異なるチェック間の時間間隔であり、camel.vault.aws.secrets
は更新を追跡するシークレットを表す正規表現です。
camel.vault.aws.secrets
は、必須ではないことに注意してください。指定されていない場合は、更新イベントのチェックを行うタスクが aws:
接頭辞を持つプロパティーを考慮します。
唯一の要件は、camel-aws-secrets-manager jar を Camel アプリケーションに追加することです。
11.5.1.6. AWS Secrets Manager を Eventbridge および AWS SQS サービスとともに使用する際に、シークレットの更新時に Camel コンテキストを自動的にリロードする
もう 1 つのオプションは、AWS EventBridge を AWS SQS サービスと組み合わせて使用することです。
AWS 側では、次のリソースを作成する必要があります。
- AWS Couldtrail トレイル
- AWS SQS キュー
- 次のような Eventbridge ルール
{ "source": ["aws.secretsmanager"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["secretsmanager.amazonaws.com"] } }
{
"source": ["aws.secretsmanager"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["secretsmanager.amazonaws.com"]
}
}
このルールにより、AWS Secrets Manager に関連するイベントがフィルタリングされます
- Eventbridge ルールの AWS SQS キューにルールターゲットを設定する必要があります。
- 上記の SQS キューに書き込むには、Eventbrige ルールに権限を与える必要があります。これを行うには、次のような json ファイルを定義する必要があります。
{ "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"<queue_arn>/SQSDefaultPolicy\",\"Statement\":[{\"Sid\": \"EventsToMyQueue\", \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"events.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"<queue_arn>\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"<eventbridge_rule_arn>\"}}}]}" }
{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"<queue_arn>/SQSDefaultPolicy\",\"Statement\":[{\"Sid\": \"EventsToMyQueue\", \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"events.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"<queue_arn>\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"<eventbridge_rule_arn>\"}}}]}"
}
queue_arn と eventbridge_rule_arn の値を変更し、policy.json という名前でファイルを保存して、AWS CLI で次のコマンドを実行します。
aws sqs set-queue-attributes --queue-url <queue_url> --attributes file://policy.json
aws sqs set-queue-attributes --queue-url <queue_url> --attributes file://policy.json
ここで、queue_url は、先ほど作成されたキューの AWS SQS キュー URL です。
これで、Camel 側で設定をセットアップできるはずです。SQS 通知を有効にするには、次のプロパティーを追加します。
camel.vault.aws.refreshEnabled=true camel.vault.aws.refreshPeriod=60000 camel.vault.aws.secrets=Secret camel.main.context-reload-enabled = true camel.vault.aws.useSqsNotification=true camel.vault.aws.sqsQueueUrl=<queue_url>
camel.vault.aws.refreshEnabled=true
camel.vault.aws.refreshPeriod=60000
camel.vault.aws.secrets=Secret
camel.main.context-reload-enabled = true
camel.vault.aws.useSqsNotification=true
camel.vault.aws.sqsQueueUrl=<queue_url>
ここで、queue_url は、先ほど作成されたキューの AWS SQS キュー URL です。
'Secret' という名前のシークレットの PutSecretValue のイベントが発生するたびに、メッセージが AWS SQS キューにエンキューされて Camel 側で消費され、コンテキストのリロードがトリガーされます。
11.5.1.7. Google Secret Manager 使用時のシークレット更新での Camel コンテキストの自動リロード
通常の認証情報 (Google Secret Manager Property 関数で使用されるものと同じ) を指定することで、シークレット更新時に Camel コンテキストをリロードできるようになります。
環境変数を使用する場合:
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true
export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
または単純な Camel のメインプロパティーとしての場合:
camel.vault.gcp.useDefaultInstance = true camel.vault.aws.projectId = projectId
camel.vault.gcp.useDefaultInstance = true
camel.vault.aws.projectId = projectId
または、デフォルトのインスタンスを使用する代わりに、サービスアカウントキーファイルへのパスを指定します。
自動更新を有効にするには、追加のプロパティーを設定する必要があります。
camel.vault.gcp.projectId= projectId camel.vault.gcp.refreshEnabled=true camel.vault.gcp.refreshPeriod=60000 camel.vault.gcp.secrets=hello* camel.vault.gcp.subscriptionName=subscriptionName camel.main.context-reload-enabled = true
camel.vault.gcp.projectId= projectId
camel.vault.gcp.refreshEnabled=true
camel.vault.gcp.refreshPeriod=60000
camel.vault.gcp.secrets=hello*
camel.vault.gcp.subscriptionName=subscriptionName
camel.main.context-reload-enabled = true
ここで、camel.vault.gcp.refreshEnabled
は自動コンテキストリロードを有効にし、camel.vault.gcp.refreshPeriod
は更新イベントの 2 つの異なるチェック間の時間間隔で、camel.vault.gcp.secrets
は更新を追跡するシークレットを表す正規表現です。
camel.vault.gcp.secrets
は必須ではないことに注意してください。指定されていない場合は、更新イベントのチェックを行うタスクが gcp:
接頭辞を持つプロパティーを考慮します。
camel.vault.gcp.subscriptionName
は、追跡されたシークレットに関連付けられた Google PubSub トピックに関連して作成されたサブスクリプション名です。
このメカニズムは、Google Secret Manager に関連する通知システムを利用します。この機能により、すべてのシークレットを 1 つから最大 10 個の Google Pubsub トピックに関連付けることができます。これらのトピックは、シークレットのライフサイクルに関連するイベントを受け取ります。
要件は 2 つだけです: - Camel アプリケーションに camel-google-secret-manager
JAR を追加します。- サービスアカウントに、シークレット管理レベルで操作を行うための権限を付与します (たとえば、シークレットペイロードにアクセスする、シークレットマネージャーサービスの管理者になる、Pubsub サービスに対する権限も持つなど)。
11.5.1.8. Azure Key Vault 使用時のシークレット更新時の Camel コンテキストの自動リロード
シークレット更新時に Camel コンテキストをリロードできるようにするには、通常の認証情報 (Azure Key Vault Property 関数で使用されるものと同じ) を指定します。
環境変数を使用する場合:
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
または単純な Camel のメインプロパティーとしての場合:
camel.vault.azure.tenantId = accessKey camel.vault.azure.clientId = clientId camel.vault.azure.clientSecret = clientSecret camel.vault.azure.vaultName = vaultName
camel.vault.azure.tenantId = accessKey
camel.vault.azure.clientId = clientId
camel.vault.azure.clientSecret = clientSecret
camel.vault.azure.vaultName = vaultName
Azure アイデンティティーを環境変数と共に使用したい場合は、次の方法で実行できます。
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
次のように、application.properties
ファイルで Azure アイデンティティーの使用を有効にすることもできます。
camel.vault.azure.azureIdentityEnabled = true camel.vault.azure.vaultName = vaultName
camel.vault.azure.azureIdentityEnabled = true
camel.vault.azure.vaultName = vaultName
自動更新を有効にするには、追加のプロパティーを設定する必要があります。
camel.vault.azure.refreshEnabled=true camel.vault.azure.refreshPeriod=60000 camel.vault.azure.secrets=Secret camel.vault.azure.eventhubConnectionString=eventhub_conn_string camel.vault.azure.blobAccountName=blob_account_name camel.vault.azure.blobContainerName=blob_container_name camel.vault.azure.blobAccessKey=blob_access_key camel.main.context-reload-enabled = true
camel.vault.azure.refreshEnabled=true
camel.vault.azure.refreshPeriod=60000
camel.vault.azure.secrets=Secret
camel.vault.azure.eventhubConnectionString=eventhub_conn_string
camel.vault.azure.blobAccountName=blob_account_name
camel.vault.azure.blobContainerName=blob_container_name
camel.vault.azure.blobAccessKey=blob_access_key
camel.main.context-reload-enabled = true
ここで、camel.vault.azure.refreshEnabled
は自動コンテキストリロードを有効にし、camel.vault.azure.refreshPeriod
は更新イベントの 2 つの異なるチェック間の時間間隔で、camel.vault.azure.secrets
は更新を追跡するシークレットを表す正規表現です。
ここで、camel.vault.azure.eventhubConnectionString
は通知を取得するイベントハブ接続文字列、camel.vault.azure.blobAccountName
、camel.vault.azure.blobContainerName
、camel.vault.azure.blobAccessKey
は、Azure Eventhub に必要なチェックポイントストアの Azure Storage Blob パラメーターです。
camel.vault.azure.secrets
は必須ではないことに注意してください。指定されていない場合、更新イベントのチェックを行うタスクは、azure:
接頭辞を持つプロパティーを考慮します。
唯一の要件は、Camel アプリケーションに camel-azure-key-vault jar を追加することです。