1. 概要

この記事では、 Camelを紹介し、そのコアコンセプトの1つであるメッセージルーティングについて説明します。

まず、これらの基本的な概念と用語について説明し、次に、ルートを定義するための2つの主要なオプションであるJavaDSLとSpringDSLを紹介します。

また、例でこれらを示します。あるフォルダーからファイルを消費して別のフォルダーに移動するルートを定義し、各ファイル名にタイムスタンプを追加します。

2. ApacheCamelについて

Apache Camel は、システムの統合をシンプルかつ簡単にするために設計されたオープンソースの統合フレームワークです。

これにより、エンドユーザーは同じAPIを使用してさまざまなシステムを統合し、複数のプロトコルとデータタイプをサポートしながら、拡張可能でカスタムプロトコルを導入できます。

3. Mavenの依存関係

Camelを使用するには、最初にMaven依存関係を追加する必要があります。

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <version>2.18.0</version>
</dependency>

キャメルアーティファクトの最新バージョンはここにあります。

3. ドメイン固有言語

ルートとルーティングエンジンはCamelの中心的な部分です。 ルートには、異なるシステム間の統合のフローとロジックが含まれています。

ルートをより簡単かつクリーンに定義するために、CamelはJavaやGroovyなどのプログラミング言語用にいくつかの異なるドメイン固有言語(DSL)を提供しています。 一方、SpringDSLを使用したXMLでのルートの定義も提供します。

ほとんどの機能は両方で利用できるため、JavaDSLまたはSpringDSLのいずれかを使用することがほとんどの場合ユーザー設定です。

Java DSLは、SpringDSLではサポートされていないもう少し多くの機能を提供します。 ただし、コードを再コンパイルしなくてもXMLを変更できるため、SpringDSLの方が有利な場合があります。

4. 用語とアーキテクチャ

次に、Camelの基本的な用語とアーキテクチャについて説明します。

まず、ここでラクダのコアコンセプトを見ていきます。

  • メッセージには、ルートに転送されているデータが含まれています。 各メッセージには一意の識別子があり、本文、ヘッダー、添付ファイルで構成されています
  • Exchange はメッセージのコンテナーであり、ルーティングプロセス中にコンシューマーがメッセージを受信したときに作成されます。 Exchangeでは、システム間のさまざまなタイプの対話が可能です。一方向メッセージまたは要求/応答メッセージを定義できます。
  • Endpoint は、システムがメッセージを送受信できるチャネルです。 WebサービスURI、キューURI、ファイル、電子メールアドレスなどを参照できます
  • Componentはエンドポイントファクトリとして機能します。 簡単に言うと、コンポーネントは、同じアプローチと構文を使用して、さまざまなテクノロジーへのインターフェイスを提供します。 Camelは、ほぼすべての可能なテクノロジーのDSLで多くのコンポーネントをすでにサポートしていますが、カスタムコンポーネントを作成する機能も提供します。
  • Processor は、ルートにカスタム統合ロジックを追加するために使用される単純なJavaインターフェースです。 これには、コンシューマーが受信したメッセージに対してカスタムビジネスロジックを実行するために使用される単一のprocessメソッドが含まれています。

大まかに言えば、Camelのアーキテクチャは単純です。 CamelContext は、Camelランタイムシステムを表し、ルート、コンポーネント、エンドポイントなどのさまざまな概念を結び付けます。

その下では、プロセッサがエンドポイント間のルーティングと変換を処理し、エンドポイントが異なるシステムを統合します。

5. ルートの定義

ルートは、JavaDSLまたはSpringDSLで定義できます。

各ファイル名にタイムスタンプを追加しながら、あるフォルダーからファイルを消費して別のフォルダーに移動するルートを定義することにより、両方のスタイルを説明します。

5.1. JavaDSLを使用したルーティング

Java DSLでルートを定義するには、最初にDefaultCamelContextインスタンスを作成する必要があります。 その後、 RouteBuilder クラスを拡張し、ルートフローを含むconfigureメソッドを実装する必要があります。

private static final long DURATION_MILIS = 10000;
private static final String SOURCE_FOLDER = "src/test/source-folder";
private static final String DESTINATION_FOLDER 
  = "src/test/destination-folder";

@Test
public void moveFolderContentJavaDSLTest() throws Exception {
    CamelContext camelContext = new DefaultCamelContext();
    camelContext.addRoutes(new RouteBuilder() {
      @Override
      public void configure() throws Exception {
        from("file://" + SOURCE_FOLDER + "?delete=true").process(
          new FileProcessor()).to("file://" + DESTINATION_FOLDER);
      }
    });
    camelContext.start();
    Thread.sleep(DURATION_MILIS);
    camelContext.stop();
}

configure メソッドは、次のように読み取ることができます。ソースフォルダーからファイルを読み取り、 FileProcessor で処理して、結果を宛先フォルダーに送信します。 delete = true を設定すると、ファイルは正常に処理された後、ソースフォルダーから削除されます。

Camelを起動するには、CamelContextstartメソッドを呼び出す必要があります。 Thread.sleep は、Camelがファイルをあるフォルダーから別のフォルダーに移動するのに必要な時間を許可するために呼び出されます。

FileProcessor は、 Processor インターフェイスを実装し、ファイル名を変更するためのロジックを含む単一のprocessメソッドを含みます。

public class FileProcessor implements Processor {
    public void process(Exchange exchange) throws Exception {
        String originalFileName = (String) exchange.getIn().getHeader(
          Exchange.FILE_NAME, String.class);

        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(
          "yyyy-MM-dd HH-mm-ss");
        String changedFileName = dateFormat.format(date) + originalFileName;
        exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName);
    }
}

ファイル名を取得するには、取引所から着信メッセージを取得し、そのヘッダーにアクセスする必要があります。 同様に、ファイル名を変更するには、メッセージヘッダーを更新する必要があります。

5.2. SpringDSLを使用したルーティング

Spring DSLでルートを定義するときは、XMLファイルを使用してルートとプロセッサを設定します。 これにより、Springを使用してコードを使用せずにルートを構成でき、最終的には制御の完全反転のメリットが得られます。

これは既存の記事ですでに説明されているため、ルートを定義するための一般的に推奨される方法であるJavaDSLとSpringDSLの両方の使用に焦点を当てます。

この配置では、CamelContextはCamelのカスタムXML構文を使用してSpring XMLファイルで定義されますが、XMLを使用する「純粋な」SpringDSLの場合のようにルート定義はありません。

<bean id="fileRouter" class="com.baeldung.camel.file.FileRouter" />
<bean id="fileProcessor" 
  class="com.baeldung.camel.file.FileProcessor" />

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="fileRouter" />
</camelContext>

このようにして、JavaDSLでルートの定義を保持するFileRouterクラスを使用するようにCamelに指示します。

public class FileRouter extends RouteBuilder {

    private static final String SOURCE_FOLDER = 
      "src/test/source-folder";
    private static final String DESTINATION_FOLDER = 
      "src/test/destination-folder";

    @Override
    public void configure() throws Exception {
        from("file://" + SOURCE_FOLDER + "?delete=true").process(
          new FileProcessor()).to("file://" + DESTINATION_FOLDER);
    }
}

これをテストするには、SpringでCamelContextをロードするClassPathXmlApplicationContextのインスタンスを作成する必要があります。

@Test
public void moveFolderContentSpringDSLTest() throws InterruptedException {
    ClassPathXmlApplicationContext applicationContext = 
      new ClassPathXmlApplicationContext("camel-context.xml");
    Thread.sleep(DURATION_MILIS);
    applicationContext.close();
}

このアプローチを使用することにより、Springによって提供される追加の柔軟性と利点、およびJavaDSLを使用することによるJava言語のすべての可能性が得られます。

6. 結論

この簡単な記事では、Apache Camelの概要を紹介し、あるフォルダーから別のフォルダーへのファイルのルーティングなどの統合タスクにCamelを使用する利点を示しました。

この例では、Camelを使用すると、ビジネスロジックに集中でき、ボイラープレートコードの量を減らすことができます。

この記事のコードは、GitHubにあります。