Apache Camel サポート

Spring Integration は、同じアプリケーションコンテキストで宣言された Apache Camel (英語) エンドポイントと通信するための API と構成を提供します。

この依存関係はプロジェクトに必要です:

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-camel</artifactId>
    <version>7.0.1</version>
</dependency>
compile "org.springframework.integration:spring-integration-camel:7.0.1"

Spring Integration と Apache Camel はエンタープライズ統合パターンを実装し、構成する便利な方法を提供しますが、プロジェクトは API と抽象化の実装に異なるアプローチを使用します。Spring Integration は、Spring コアの依存性注入コンテナーに完全に依存しています。チャネルアダプターの実装には、他の多くの Spring プロジェクト (Spring Data、Spring AMQP、Spring for Apache Kafka など) を使用します。また、開発者が統合フローを作成するときに認識する必要がある 第一級オブジェクトとして MessageChannel 抽象化も使用されます。一方、Apache Camel はメッセージチャネルの 第一級オブジェクト抽象化を提供せず、API から隠蔽された内部交換を介してルートを構成することを提案しています。さらに、Spring アプリケーションで使用するには、いくつかの追加の依存関係と構成 [Apache] (英語) が必要です。

最終的なエンタープライズ統合ソリューションには関係ないとしても、その各部の実装方法、開発者エクスペリエンス、高い生産性が考慮されます。開発者は、さまざまな理由から、または一部のターゲットシステムのサポートにギャップがある場合はその両方から、あるフレームワークを別のフレームワークよりも選択する場合があります。Spring Integration および Apache Camel アプリケーションは、チャネルアダプターを実装する多くの外部プロトコルを介して相互に対話できます。たとえば、Spring Integration フローは、コンシューマー側の Apache Camel エンドポイントによって消費されるレコードを Apache Kafka トピックに発行する場合があります。または、Apache Camel ルートは、ディレクトリの SFTP ファイルにデータを書き込む場合があります。これは、Spring Integration からの SFTP 受信チャネルアダプターによってポーリングされます。または、同じ Spring アプリケーションコンテキスト内で、ApplicationEvent を介して通信できます。

開発プロセスを簡素化し、不要なネットワークホップを回避するため、Spring Integration では、Apache Camel エンドポイントを呼び出し、オプションで応答を待機するためのチャネルアダプターが提供されるようになりました。Apache Camel の Bean 結合 [Apache] (英語) を使用すれば、メッセージングゲートウェイを含む Spring アプリケーションコンテキスト内の任意の Bean を呼び出すことができるため、受信チャネルアダプターは存在しません。

Apache Camel 用送信 チャネルアダプター

CamelMessageHandler は AbstractReplyProducingMessageHandler 実装であり、一方向(デフォルト)モードとリクエスト応答モードの両方で動作します。org.apache.camel.ProducerTemplate を使用して org.apache.camel.Endpoint に送信(または送受信)します。対話モードは ExchangePattern オプションによって制御できます(これは実行時にリクエストメッセージに対して SpEL 式を介して評価できます)。ターゲット Apache Camel エンドポイントは、明示的に設定することも、実行時に評価される SpEL 式として設定することもできます。それ以外の場合は、ProducerTemplate で提供される defaultEndpoint にフォールバックします。エンドポイントを指定する代わりに、インラインで明示的な LambdaRouteBuilder を提供して、たとえば Spring Integration でチャネルアダプターがサポートされていない Apache Camel コンポーネントを呼び出すことができます。

さらに、HeaderMapper<org.apache.camel.Message> (CamelHeaderMapper がデフォルト実装) を提供して、Spring Integration メッセージと Apache Camel メッセージ間でどのヘッダーをマップするかを決定できます。デフォルトでは、すべてのヘッダーがマップされます。

CamelMessageHandler は、ProducerTemplate.asyncSend() を呼び出し、応答処理 (存在する場合) のために CompletableFuture を生成する async モードをサポートします。

exchangeProperties は、Map に評価される必要がある SpEL 式を介してカスタマイズできます。

ProducerTemplate が指定されていない場合は、アプリケーションコンテキストから解決された CamelContext Bean を介して作成されます。

@Bean
@ServiceActivator(inputChannel = "sendToCamel")
CamelMessageHandler camelService(ProducerTemplate producerTemplate) {
    CamelHeaderMapper headerMapper = new CamelHeaderMapper();
    headerMapper.setOutboundHeaderNames("");
    headerMapper.setInboundHeaderNames("testHeader");

    CamelMessageHandler camelMessageHandler = new CamelMessageHandler(producerTemplate);
    camelMessageHandler.setEndpointUri("direct:simple");
    camelMessageHandler.setExchangePatternExpression(spelExpressionParser.parseExpression("headers.exchangePattern"));
    camelMessageHandler.setHeaderMapper(headerMapper);
    return camelMessageHandler;
}

Java DSL フロー定義の場合、このチャネルアダプターは、Camel ファクトリによって提供されるいくつかのバリアントで構成できます。

@Bean
IntegrationFlow camelFlow() {
    return f -> f
            .handle(Camel.gateway().endpointUri("direct:simple"))
            .handle(Camel.route(this::camelRoute))
            .handle(Camel.handler().endpointUri("log:com.mycompany.order?level=WARN"));
}

private void camelRoute(RouteBuilder routeBuilder) {
    routeBuilder.from("direct:inbound").transform(routeBuilder.simple("${body.toUpperCase()}"));
}