Spring BootでApache Camelを始めてみる(formerly Fuse)

こんにちは。ソリューションアーキテクトの瀬戸です。

今回はApache Camelアプリケーションの開発環境のセットアップをしてサンプルアプリを確認してデプロイまでをしてみたいと思います。

Apache Camelって何よ?って思った人は、蒸野さんが書いているブログ記事:Apache Camel 超入門を参照してください。

rheb.hatenablog.com

以前Red HatではFuseという名前でApache Camelを製品化して販売していました。 今はRed Hat build of Apache Camelという名前で製品化されているのですが、Red Hat build of Apache Camelに変わった後も複雑な経緯によってドキュメントの体系が変わっており、細心のドキュメントが見つけにくくなっています。 現時点(2024年11月時点)では、製品ドキュメントのページからRed Hat build of Apache Camelのリンクをたどったものが最新のドキュメントです。 それ以外については、すでにリタイヤしているものや、もうすぐリタイヤするもののドキュメントとなります。

googleで apache camel red hatで検索するとFuseのドキュメントが最初に引っかかってしまいますが、そちらはすでに古いものとなっています。

現時点(2024年11月)でのサポートされている最新のバージョンはRed Hat build of Apache Camel 4.4です。 ドキュメントのページによってはRed Hat build of Apache Camel for Spring Boot 3.20までしかバージョン一覧から選べないものもありますのでご注意ください。

重ねますが、以下が2024年11月時点での最新のドキュメントになりますのでご注意ください。

docs.redhat.com

Apache Camelを実際に使用する

Apache Camel自体はただのライブラリです。動かすためには別途アプリケーションサーバーが必要になります。 現時点ではサポートされる環境としてSpring-BootかQuarkusを選択することができます。Spring-Bootを選択することで多くの人が慣れているSpring-BootのAPIを使用する事ができます。 Quarkusを選択するとSpring-Bootよりも軽快に動作することが期待できます。

今回は、Spring-Bootを利用します。

Note: Camelのランタイムとして他にCamel Kもありますが、Camel Kのサポートは来年半ばには終了するため、新規に使い始めることは出来ません。
https://access.redhat.com/ja/articles/7083689

Spring-BootでApache Camelで開発するためにはJavaの開発環境が必要になります。OpenJDKのインストールやMavenの設定が必要になります。

設定をしたことがない場合は、以下の記事で説明しています。以下の記事ではJBoss EAPの開発環境を構築していますが、全く同じです。

rheb.hatenablog.com

開発環境さえあれば Red Hat build of Apache Camel for Spring Boot のスタートガイド の通りに行えばプロジェクトを作成できますが、簡単に作成するために今回はMavenのアーキタイプを利用します。

MavenのアーキタイプはJavaアプリケーションのテンプレートをMaven Repositoryに登録しておく仕組みです。 いくつかのパラメーターを入力することでMavenでのアプリケーション開発のサンプルを簡単に作ることができます。 アーキタイプの詳細についてはMavenのウェブサイトを参照してください。

maven.apache.org

また、Eclipse等を使用する事でどのようなアーキタイプが登録されているかを検索することもできます。

次の図はEclipseで新規プロジェクトの作成時にMavenアーキタイプの一覧を表示しています。

Maven アーキタイプの検索

さて、話はそれましたが、Red Hatのサポートの元Apache Camelを使用する場合にどのアーキタイプを指定するかについてはドキュメントに記載されています。

docs.redhat.com

ドキュメント通りにコマンドを叩きます。

mvn archetype:generate -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-spring-boot -DarchetypeVersion=4.4.0.redhat-00033 -DgroupId=com.redhat -DartifactId=csb-app -Dversion=1.0-SNAPSHOT -DinteractiveMode=false

※このうち、-DgroupIdと-DartifactId、-Dversionについては自由に変更することができます。artifactIdがフォルダ名になることだけ注意してください。

この指定のまま作成したプロジェクトをgithub上に準備しています。

github.com

このアーキタイプから作成されたプロジェクトにはサンプルアプリケーションが含まれています。 先のドキュメント通りやれば動くことは確認ができるので、中身のソースを見てみましょう。

Javaのソースコードとしては次の4つが含まれています。

  • MySpringBean.java CamelからJavaのメソッド呼び出しのサンプルを実行するために準備されたクラス
  • MySpringBootApplication.java Spring Bootアプリケーションの起動に使用するブートストラップ
  • MySpringBootRouter.java Camelの設定が含まれるクラス
  • MySpringBootApplicationTest.java Camelをテストするために利用するクラス

この中で見るべきクラスはMySpringBootRouter.javaとMySpringBootApplicationTest.javaです。

まずは、MySpringBootRouter.javaを見ていきましょう。

MySpringBootRouter.java

package com.redhat;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

/**
 * A simple Camel route that triggers from a timer and calls a bean and prints to system out.
 * <p/>
 * Use <tt>@Component</tt> to make Camel auto detect this route when starting.
 */
@Component
public class MySpringBootRouter extends RouteBuilder {

    @Override
    public void configure() {
        from("timer:hello?period={{timer.period}}").routeId("hello")
            .transform().method("myBean", "saySomething")
            .filter(simple("${body} contains 'foo'"))
                .to("log:foo")
            .end()
            .to("stream:out");
    }

}

ここではApache Camelの特徴であるJava DSLを使った処理を確認できます。Apache Camelではメソッドチェーンを利用して処理を組み立てていきます。何をしているかは読めばなんとなくわかるでしょう。 {{}}で囲われてる部分はSpring-Bootの機能を使用してapplication.propertiesから値が読み込まれています。 application.propertiesには timer.period=2000 と指定されているため、 timer:hello?period={{timer.period}} は実際には timer:hello?period=2000 として解釈されています。

Apache Camelではモジュールを組み合わせることで処理を追加でき、これはTimerコンポーネントで実装されています。

docs.redhat.com

Maven依存関係を追加して、オプションを追加してあげることで動作します。

慣れてる人はどういうコンポーネントがあるのか、パラメーターとして何を指定すればいいのかある程度わかるのですが、慣れてない人は途方に暮れてしまいます。初心者でもわかりやすいようにRed HatではkaotoというRed Hat Build of Apache Camel 4.x 向け開発ツールを提供しています。 詳細については古市さんが書いてくださってるのでそちらを参照してください。

rheb.hatenablog.com

MySpringBootApplicationTest.java

続いてテストの方を見ていきます。Apache CamelではJUnitをフォローする形でテスト用のツールが付いています。

package com.redhat;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@CamelSpringBootTest
public class MySpringBootApplicationTest {

    @Autowired
    private CamelContext camelContext;

    @Autowired
    private ProducerTemplate producerTemplate;

    @Test
    public void test() throws Exception {
        MockEndpoint mock = camelContext.getEndpoint("mock:stream:out", MockEndpoint.class);

        AdviceWith.adviceWith(camelContext, "hello",
                // intercepting an exchange on route
                r -> {
                    // replacing consumer with direct component
                    r.replaceFromWith("direct:start");
                    // mocking producer
                    r.mockEndpoints("stream*");
                }
        );

        // setting expectations
        mock.expectedMessageCount(1);
        mock.expectedBodiesReceived("Hello World");

        // invoking consumer
        producerTemplate.sendBody("direct:start", null);

        // asserting mock is satisfied
        mock.assertIsSatisfied();
    }
}

こちらも何をしようとしているのかは簡単にわかるのではないかと思います。

AdviceWithクラスの中でApache Camelの中身の設定(fromとto)を書き換えています。 その結果、実行し出力される内容が想定通りか(mock#expectedBodiesReceivedの内容と同じか)を確認しています。

Apache CamelはインテグレーションツールとしてIN/OUTを固めやすいため、テストもしやすいです。

OpenShiftへのデプロイ

今回のApache Camelは通常のSpring-Bootアプリケーションのため、前回の記事、Spring-Bootアプリケーションのbootable jarをOpenShiftにデプロイするにて書いたとおりの手順でデプロイできます。

ただ、前回の記事で、OpenShiftはCI/CDに関わる機能も備えており、OpenShift上でGitHub等から直接ソースコードを取得してビルドをし、デプロイすることができます。 と書きましたが、そちらの説明をしていないため、今回はその説明をしたいと思います。

OpenShiftへのソースコードを指定してデプロイする場合のMavenの設定

OpenShiftへのデプロイは柔軟なため、いろいろデプロイする方法はあるのですが、ソースコードを直接取得し、OpenShift上でビルドし、デプロイするために一番簡単な方法はOpenShiftのイメージストリームの仕組みを使う事です。 詳細な説明は除きますが、そのためにはMavenのpom.xmlにopenshiftという名前の付いたprofileを準備しておく必要があります。 今回のアーキタイプで指定したプロジェクトではすでに設定されています。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
(中略)
  <profiles>
    <profile>
      <id>openshift</id>
      <build>
        <defaultGoal>install</defaultGoal>
        <plugins>
          <plugin>
            <groupId>org.eclipse.jkube</groupId>
            <artifactId>openshift-maven-plugin</artifactId>
            <version>1.16.2.redhat-00017</version>
            <executions>
              <execution>
                <goals>
                  <goal>resource</goal>
                  <goal>build</goal>
                  <goal>apply</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

openshift-maven-pluginはfabric8-maven-plugin から置き換えられたものです。OpenShift上のリソースを操作することもできます。どういうことができるのかについてはドキュメントを参照してください。

eclipse.dev

コマンドライン上から単純にgithubのリポジトリを指定して実行することでデプロイすることができます。

oc new-app https://github.com/ssetoredhat/csb-app

この設定は他のSpring-Bootアプリケーションやfat-jarを生成するアプリケーションでも有効です。ソースコードから自動的にmavenを使用してビルドをし、デプロイをしてくれます。

おわり

Apache Camelのドキュメントの紹介からプロジェクトの始め方、OpenShiftのデプロイまでを簡単に説明しました。 簡単に試せるのが利点だと思いますので、ぜひ参考にしてみてください。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。