Camel In Action の1章の適当邦訳 〜Apache Camel その5

blog1.mammb.com
からの続き


1.4 Camel のアーキテクチャ
それでは Camel のアーキテクチャに焦点をあてていきましょう。最初にアーキテクチャの概要から見ていき、その後で特定のコンセプトについて詳細に見ていくことにします。この章を読み終われば、第2章に進むために必要となるインテグレーションに関する専門用語が理解できるようになるでしょう。第2章では Camel のルーティングについて詳しく見ていくことになります。

10,000フィートからのアーキテクチャ

アーキテクチャは最初に高い視点から見渡すのが良いでしょう。以下に Camel のアーキテクチャのコンセプトの概要を示します。



ルーティングエンジン(Routing engine)はメッセージをどのようにルートするかという仕様として route を使用します。ルートは Camel のドメイン固有言語(DSL)の1つを使用して定義されます。
Processors はルーティング期間においてメッセージの変換と操作のために使用されます。Processors は EIP パターンの実装であり、DSL において、EIPパターンと同名の実装として扱えます。
Components は他システムへの接続方式を Camel に追加するための拡張ポイントです。Camel 単体ではサポートしない接続方式を Camel が取り扱うために、コンポーネントはエンドポイントインターフェースを提供します。
高い視点から見た後は、個々の概念について詳しく見ていきましょう。

1.4.2 Camel concepts

先の図では新しいコンセプトが明らかになりました。それぞれについて一つずつ時間を取って見ていきましょう。最初は Camel のランタイムである CamelContext から見ていきます。

Camel コンテクスト

先の図を見て、もしかしたら あなたは CamelContext をある種のコンテナのように想像しているかも知れません。しかしそうではなく、CamelContext はすべてのピースを協調させるための Camel のランタイムシステムと考えてください。CamelContext と協調動作する特に顕著なサービスを以下に示します。



この図から、CamelContext が扱うたくさんのサービスがあることが分かります。詳細を以下の表にまとめます。

サービス 詳細
Components 利用されるコンポーネントです。Camel はクラスパス上から、またはOSGiコンテナで活性化した新しいバンドルのどちらでもその場でロードできます。第7章ではコンポーネントについて詳細に見ていきます。
Endpoints 作成されたエンドポイントです。
Routes 追加されたルートです。第2章でルートについて取り上げます。
Type converters ロードされた型コンバータです。Camel は手動または自動的にある型を他の型に変換する仕組みを持っています。型コンバータについては第3章で扱います。
Data formats ロードされたデータフォーマットです。データフォーマットは第3章で扱います。
Registry Beans ルックアップを可能とするレジストリです。デフォルトでは JNDI レジストリが使用されます。Camel を Spring から利用している場合は Spring の ApplicationContext となります。OSGi コンテナ上で Camel を利用している場合は OSGi レジストリとなります。詳しくは第4章で扱います。
Languages ロードされた言語です。Camel は式の作成に多くの異なる言語を利用できます。Camel の扱う DSL にて XPath 表記が垣間見れたりします。Camel 固有のシンプルな式言語は appendix A に完全なリファレンスを掲載します。


それぞれのサービスについては本書の中で詳しく説明していきます。それではここで、Camel のルートとルーティングエンジンについて見ていきましょう。

ルーティングエンジン

Camel のルーティングエンジンは背後に隠れてメッセージの移動に徹します。このエンジンは開発者には公開されていませんが、ルーティングエンジンが存在し、困難な仕事の受け持ち、メッセージが適切にルーティングされることを確実にしている ということは覚えておく必要があります。

ROUTES

ルート(Routes)はまさに、Camel の主要な抽象と言えるでしょう。ルートを定義する簡単な方法は処理をチェーンさせた形で行われます。メッセージングアプリケーションにおいて、ルータを使用するのは様々な理由があります。サーバからクライアントを分離するためであったり、プロデューサとコンシューマを分離するためであったりします。ルートは次のようなことを実現します。

  • クライアントが起動されるとサーバが動的に決定されます。
  • 追加の処理を柔軟に加える方法を提供します。
  • クライアントとサーバの開発を分離して実施できます。
  • テスト目的で、サーバをスタブアウト(モックを利用)してクライアントから利用できます。
  • ある事柄をうまく行う接続ディスパッチャシステムのための良い設計プラクティスです。
  • あるシステムの機能と機能性を強化する(メッセージブローカーとESBsのように)。

Camel での各ルートは一意の識別子を持っています。この識別子はロギングやデバッギング、モニタリング、そしてルートの起動と停止に使われます。ルートはまた、メッセージのための一つだけの入力元を持っているため、入力エンドポイントと効果的に関連付けされます。ルートを定義するためには DSL が利用されます。

ドメイン固有言語(DSL)

処理とエンドポイントをルートによってつなぎ合わせるために Camel は DSL を定義しています。DSL という用語はすこし曖昧ですね。Camel における DSL は EIP の用語から命名されたメソッドを含む Java の流れるような API となっています。以下の例を考えてみましょう。

from("file:data/inbox")
    .filter().xpath("/order[not(@test)]")
    .to("jms:queue:order")

ここでのJavaの単一のステートメントは、ファイルのエンドポイントからファイルを消費するルートを定義しています。メッセージは、XPathによる述語表現されたEIPのフィルタによりルーティングされます。XPathではメッセージがtestの順序であるかどうかをテストしています。メッセージがテストに合格した場合には JMS エンドポイントに転送され、失敗した場合にはフィルタにより除外されます。
Camel は DSL として利用できる言語を複数提供しています。同様のルート定義を Spring DSL で書くと次のようになります。

<route>
  <from uri="file:data/inbox"/>
  <filter>
    <xpath>/order[not(@test)]</xpath>
    <to uri="jms:queue:order"/>
  </filter>
</route>

DSL は Camel ユーザがアプリケーション構築の際に使用できる良い抽象を提供しているのです。この背後では、実際にはルートはプロセッサのグラフにより構成されています。ではプロセッサが実際にどのようなものか見てみましょう。

PROCESSOR(プロセッサ)

プロセッサは、入力となる exchange を、利用する、作成する、まはた修正するといったことができるノードを表す Camel の中心的な概念です。ルーティングの最中に、exchange はあるプロセッサから他のプロセッサに流れていきます。ルートは、ノードとして特化したプロセッサを持つグラフであると考えることができます。そしてこのノードは一つのプロセッサの出力を別の入力に接続します。多くのプロセッサは EIP の実装となりますが、独自のプロセッサを実装することも簡単にでき、ルートの中に入れ込むことができます。
それでは、プロセッサグラフの入力や出力からどのように exchange を得るのでしょうか。それを調べるために、コンポーネントとエンドポイントを見ていく必要があります。

コンポーネント

コンポーネントは Camel における主要な拡張ポイントです。現在 Camel エコシステムには 80 を超えるコンポーネントがあります。データ変換から、DSL用、データフォーマットなどに至る機能があります。Camel にて独自のコンポーネントを作成することもでき、これについては第11章にて述べていきます。
プログラミングの観点から見ると、コンポーネントは非常にシンプルです。コンポーネントは URI を使用して名前が関連付けられており、エンドポイントのファクトリとして機能します。例えば、FileComponent は URI 指定される file から参照されており、FileEndpoints を作成します。エンドポイントは恐らく Camel において最も基本的なコンセプトです。



blog1.mammb.com
に続く