Apache Camel Advent Calendar 13日目の記事は、サポート担当古市が担当します。 テーマは、「Camel routeTemplate」

サポートでたまにあるお問い合わせには、「コード量が多くどの箇所が問題になっているかわからない。とりあえずソースコードは全て添付する。」といったものです。 開発と運用が分かれているからといった理由の他には、見本となる camel routeを複製することで業務対応しているケースもありました。(数百もの camel ルートがほぼ複製されたものといったケースも)
厳密にはリファクタリングを通して2つか 3つの camelルートへ集約することが可能であったりしますが、開発コストや技術者の育成/引き継ぎを懸念されていらっしゃるのかもしれません。 そんな現場の皆さんへぜひ知っておいてほしいのが、camel routeのテンプレート機能となる、「camel routeTemplate」です。
その名の通り、雛形の camelルートを作成し、利用者は虫食いとなっているパラメーターに必要な値を設定しながらルートを複製するだけです。 これならば、雛形の camelルートを修正したい場合、修正箇所は1つとなります。(camelルートを全てコピーされていた場合、修正箇所はコピーした分だけ膨れ上がります。もちろん、コピーした camelルートをどのように修正したかそれぞれ確認する必要もあるため、メンテナンスコストは膨大に膨れ上がります。)
コミュニティードキュメントを一通り読んで試していただきたいのですが、ここでは基本となるサンプルを試してみます。 こちらが、雛形の camel ルートと、雛形を使った2つの camel ルートです。
@Override
public void configure() throws Exception {
routeTemplate("myTemplate")
.templateParameter("name")
.templateParameter("greeting")
.templateParameter("myRepeatCount", "1")
.from("timer:{{name}}?repeatCount={{myRepeatCount}}")
.setBody(simple("{{greeting}} ${body}"))
.log("${body}");
templatedRoute("myTemplate")
.routeId("route1")
.parameter("name", "one")
.parameter("greeting", "Hello");
templatedRoute("myTemplate")
.routeId("route2")
.parameter("name", "two")
.parameter("greeting", "Bonjour")
.parameter("myRepeatCount", "2");
}
もちろん、雛形の camelルートを定義したクラスと、雛形を使った camelルートを定義するクラスを分けることも可能です。分けたサンプルはこちらにあります。 https://github.com/apache/camel-examples/tree/main/routetemplate/src/main/java/org/apache/camel/example
camel-timer consumer の repeatCount オプションにはデフォルト値(1)も設定してあるため、雛形を使ったクラスがパラメーターを指定しなかった場合、デフォルト値が使われます。 実行結果はこのようになります。
2025-09-24 16:39:53.907 INFO 43715 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.14.0 (ObserveRouteTemplate) is starting 2025-09-24 16:39:53.951 INFO 43715 --- [ main] org.apache.camel.main.BaseMainSupport : Property-placeholders summary 2025-09-24 16:39:53.951 INFO 43715 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] name = two 2025-09-24 16:39:53.951 INFO 43715 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] myRepeatCount = 2 2025-09-24 16:39:53.951 INFO 43715 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] greeting = Bonjour 2025-09-24 16:39:54.005 INFO 43715 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:2 templates:2) 2025-09-24 16:39:54.005 INFO 43715 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route1 (timer://one) 2025-09-24 16:39:54.005 INFO 43715 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route2 (timer://two) 2025-09-24 16:39:54.005 INFO 43715 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.14.0 (ObserveRouteTemplate) started in 98ms (build:0ms init:0ms start:98ms boot:595ms) 2025-09-24 16:39:54.959 INFO 43715 --- [5 - timer://one] route1 : Hello 2025-09-24 16:39:54.959 INFO 43715 --- [6 - timer://two] route2 : Bonjour 2025-09-24 16:39:55.954 INFO 43715 --- [6 - timer://two] route2 : Bonjour
ルートIDも指定してある為、ログの視認性も良いです。 これならば、camel ルートを安全に複製していただき、メンテナンス性も飛躍的に向上するはずです。ぜひお試しください。
雛形を使うのにコーディングをしたくないといった場合には、application.properties を使い雛形を使ったルートを作成することもできます。
camel.route-template[route1].template-id=myTemplate camel.route-template[route1].name=one camel.route-template[route1].greeting=Hello camel.route-template[route2].template-id=myTemplate camel.route-template[route2].name=two camel.route-template[route2].greeting=Bonjour camel.route-template[route2].myRepeatCount=2
[]の中には、routeId を指定しています。 クラスでは、雛形の定義しかしていません。
@Override
public void configure() throws Exception {
routeTemplate("myTemplate")
.templateParameter("name")
.templateParameter("greeting")
.templateParameter("myRepeatCount", "1")
.from("timer:{{name}}?repeatCount={{myRepeatCount}}")
.setBody(simple("{{greeting}} ${body}"))
.log("${body}");
実行結果はこのようになります。
2025-09-24 14:35:28.616 INFO 33800 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.14.0 (ObserveRouteTemplate) is starting 2025-09-24 14:35:28.659 INFO 33800 --- [ main] org.apache.camel.main.BaseMainSupport : Property-placeholders summary 2025-09-24 14:35:28.660 INFO 33800 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] name = two 2025-09-24 14:35:28.660 INFO 33800 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] myRepeatCount = 2 2025-09-24 14:35:28.660 INFO 33800 --- [ main] org.apache.camel.main.BaseMainSupport : [LocalProperties] greeting = Bonjour 2025-09-24 14:35:28.712 INFO 33800 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:2 templates:2) 2025-09-24 14:35:28.712 INFO 33800 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route1 (timer://one) 2025-09-24 14:35:28.712 INFO 33800 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route2 (timer://two) 2025-09-24 14:35:28.712 INFO 33800 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.14.0 (ObserveRouteTemplate) started in 96ms (build:0ms init:0ms start:96ms boot:591ms) 2025-09-24 14:35:29.668 INFO 33800 --- [6 - timer://two] route2 : Bonjour 2025-09-24 14:35:29.668 INFO 33800 --- [5 - timer://one] route1 : Hello 2025-09-24 14:35:30.668 INFO 33800 --- [6 - timer://two] route2 : Bonjour
camel-jbang コマンドで、2つの camel ルートが稼働していることも確認できます。
% camel get route PID NAME ID FROM REMOTE STATUS AGE COVER MSG/S TOTAL FAIL INFLIGHT MEAN MIN MAX LAST DELTA SINCE-LAST 33800 ObserveRouteTemplate route1 timer://one?repeatCount=1 Started 20s 2/2 0.00 1 0 0 3 3 3 3 +3 20s/20s/- 33800 ObserveRouteTemplate route2 timer://two?repeatCount=2 Started 20s 2/2 0.00 2 0 0 1 0 3 0 -3 19s/19s/- %
明日の advent calendar 14日目では、「kamelet」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com