レッドハットでコンサルティングしているフェンです。
最近、Red Hat Fuseの使ったプロジェクトで設計標準と開発標準の支援しています。そこで発生した現実な課題と解決策を皆さんに共有します。
因みに、同じ内容をQiitaでも公開しています。
Processor中でCamelコンポーネントの利用する方法 - Qiita
初心者向け用語の定義
Processorとは、データ加工用部品、Apache Camelにて提供されているメッセージの加工やルーティングを行うための部品です。 注意: ここでは、カスタム開発したProcessorを指します。
Camelコンポーネントとは、外部接続用部品、Apache Camelにて提供されている設定でいろいろなシステムに接続できる標準で実装されている部品です。
背景
Camelの使ったComposite Serviceの開発標準化していく中で出てきた話題がありました。
Camel Routeは、VETROデザインパターンの処理フローの制御に適合しますが、プログラミング要素の強いロジックがやはりProcessor(データ加工用部品)が一番適任だと感じました。
そして、ProcessorでもCamelコンポーネント(外部接続用部品)が使えると便利ですねという発想が生まれました。
と言うわけで、Processor中でCamelコンポーネントの利用する方法を調べました。
結論は、ProducerTemplateを使えば簡単にできました。
ProducerTemplateとは
ProducerTemplate とは、Camelで用意されたインタフェースです。
このインタフェースを利用することで、Javaコード(Processor, Bean)の中でCamelが用意された豊富なコンポーネントを簡単にインスタンス化し、外部システムと送受信できるようになります。
今回実装したサンプルでは、Processorの中で、HTTPコンポーネントを使ったリクエストレスポンスの実現方法を紹介します。
サンプルのMavenプロジェクトは、https://github.com/jian-feng/producer-template-sample に置いてあります。
実装方法
1. camel-context.xml
camelContext内で<template>
(ProducerTemplateのこと)を初期化します。
また、MyProcessorはこのtemplate、とendpointUriで初期化します。
<bean id="myprocessor" class="org.mycompany.MyProcessor"> <property name="producer" ref="myTemplate" /> <property name="endpointUri" value="http://inet-ip.info/ip"/> </bean> <camelContext id="camel" ... > <template id="myTemplate" /> ... </camelContext>
2. MyProcessor.java
@Override public void process(Exchange exchange) throws Exception { // camel-contextにて初期化されたProducerTempalteを使ってリクエストレスポンスを実行します。 String respBody = producer.requestBody(endpointUri,"test message from myprocessor", String.class); LOG.info("respBody={}", respBody); // ProducerTemplateから得られたレスポンスを現在処理中のExchangeにセットします。 exchange.getIn().setBody(respBody); }
3. camel-context.xml
camelContext内のCamel Routeは以下に定義します。
<route> ... <log id="log1" message="body before myprocessor >>> ${body}" /> <process ref="myprocessor" /> <log id="log2" message="body after myprocessor >>> ${body}" /> </route>
実行方法
mvn spring-boot:run
このサンプルを実行すると、10秒間隔で、MyProcessorの中から指定のendpointUri(Camelコンポーネントが使われる)にアクセスし、endpointのレスポンスをログに出力します。
[Camel (camel) thread #1 - timer://foo] INFO simple-route - body before myprocessor >>> Hello World from camel-context.xml
[Camel (camel) thread #1 - timer://foo] INFO MyProcessor - respBody=xx.xx.xx.xx
[Camel (camel) thread #1 - timer://foo] INFO simple-route - body after myprocessor >>> xx.xx.xx.xx
- 1行目のログは、simple-routeがMyProcessor実行前Bodyの出力
- 2行目は、MyProcessorの中でendpointのレスポンスをログに出力
- 3行目は、simple-routeがMyProcessor実行後Bodyの出力
- 1 - 3は、同じスレッドで処理されていること