Apache-camel-quick-guide
Apache Camel-はじめに
インドのBigbasketなど、あなたの町にある大規模なオンライン食料品店がITソリューションの設計に招待する状況を考えてみましょう。 安定したスケーラブルなソリューションは、今日直面しているソフトウェアメンテナンスの問題を克服するのに役立ちます。 このオンラインストアは、過去10年間ビジネスを運営しています。 ストアは、顧客からのさまざまなカテゴリーの製品のオンライン注文を受け入れ、それらをそれぞれのサプライヤーに配布します。 たとえば、石鹸、オイル、牛乳を注文するとします。これら3つのアイテムは、それぞれ3つのサプライヤに配布されます。 その後、3つのサプライヤは、配送センターによって注文全体が履行される共通の配布ポイントにサプライ品を送信します。 さて、今日彼らが直面している問題を見てみましょう。
このストアが事業を開始したとき、コンマ区切りのプレーンテキストファイルで注文を受け付けていました。 ある期間にわたって、ストアはメッセージ駆動型の発注に切り替わりました。 後に、一部のソフトウェア開発者はXMLベースの発注を提案しました。 最終的に、ストアはWebサービスインターフェイスを採用しました。 さて、ここに本当の問題があります。 注文は現在、さまざまな形式で提供されています。 明らかに、会社が注文受付フォーマットをアップグレードするたびに、顧客の心に混乱を引き起こさないために、以前にデプロイされたインターフェースを壊したくありませんでした。
同時に、ビジネスの成長に伴い、店舗は定期的に新しいサプライヤーをレパートリーに追加しました。 そのようなサプライヤーはそれぞれ、注文を受け入れるための独自のプロトコルを持っています。 ここでも、統合の問題に直面しています。当社のアプリケーションアーキテクチャは、新しいサプライヤが独自の発注メカニズムで対応できるようにスケーラブルでなければなりません。
全体の状況は、次の図に示されています-
ここで、Apache Camelがどのようにあなたを助けて、説明されたシナリオのためのエレガントで、保守可能で、スケーラブルなソリューションアーキテクチャを提供できるかを見てみましょう。
解決策を進める前に、小さな仮定をする必要があります。 このチュートリアルのすべての説明では、オンライン注文がXML形式で行われることを前提としています。 ディスカッション全体で使用する注文ファイルの一般的な形式を次に示します-
<?xml version = "1.0" encoding = "UTF-8"?>
<OrderID Order = "001">
<order product = "soaps">
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
</order>
<order product = "Oil">
<items>
<item>
<Brand>Saffola</Brand>
<Type>Gold</Type>
<Quantity>2</Quantity>
<Price>649</Price>
</item>
<item>
<Brand>Fortune</Brand>
<Type>Sunlite</Type>
<Quantity>1</Quantity>
<Price>525</Price>
</item>
</items>
</order>
<order product = "Milk">
<items>
<item>
<Product>Milk</Product>
<Brand>Amul</Brand>
<Type>Pure</Type>
<Quantity>2</Quantity>
<Price>60</Price>
</item>
</items>
</order>
</OrderID>
このチュートリアルでは、上記のXMLテンプレートを使用してCamelの例を説明します。
Apache Camel-概要
キャメルは、あるエンドポイントからメッセージを受信し、別のエンドポイントに送信するブラックボックスです。 ブラックボックス内で、メッセージは処理されるか、単にリダイレクトされます。
では、なぜこのためのフレームワークがあるのでしょうか? 導入事例で見られるような実際の状況では、多数の送信者と多数の受信者がいて、それぞれがftp、http、jmsなどの独自のプロトコルに従っている場合があります。 システムは、送信者AからのメッセージをB&Cにのみ配信するなど、多くの複雑なルールを必要とする場合があります。 状況によっては、受信者が期待する別の形式にメッセージを変換する必要があります。 この翻訳には、メッセージの内容に基づいて特定の条件が適用される場合があります。 したがって、基本的には、プロトコル間の変換、コンポーネントの接着、ルーティングルールの定義、メッセージの内容に基づくフィルタリングの提供が必要になる場合があります。 これは、次の図に示されています-
上記の要件を満たし、このような多くの状況に適したソフトウェアアーキテクチャを設計するために、Enterprise Integration Patterns(https://www.informit.com/store/enterprise-integration-patterns-designing-building-9780321200686[EIP])が文書化されました2003年にグレゴール・ホーペとボビー・ウルフ。 Apache Camelはこれらのパターンの実装を提供します。このチュートリアルの目的は、「はじめに」で説明したような状況でCamelを使用する方法を教えることです。
Apache Camelはオープンソースのフレームワークです。 これは、ルールベースのルーティングおよびメディエーションエンジンを提供するメッセージ指向のミドルウェアです。 「牛乳」注文の場合は牛乳ベンダーにリダイレクトするか、「油」注文の場合は石油ベンダーにリダイレクトするかなどのルールを定義できます。 Camelを使用すると、これらのルールを実装し、使い慣れたJavaコードでルーティングを実行できます。 つまり、使い慣れたJava IDEを使用して、タイプセーフ環境でこれらのルールを定義できるということです。 通常、かさばる傾向があるXML構成ファイルを使用する必要はありません。 ただし、ルールの構成にXMLを使用する場合、CamelはSpringフレームワークを介したXML構成をサポートします。 Scalaが好きなら、Blueprint XML構成ファイルやScala DSLを使用することもできます。 また、お気に入りのJava、Scala IDE、または単純なXMLエディターを使用してルールを構成できることも意味します。
このエンジンへの入力は、カンマ区切りのテキストファイル、POJO(Plain Old Java Object)、XMLはCamelでサポートされている他のいくつかの形式のいずれかです。 同様に、エンジンの出力をファイル、メッセージキュー、またはモニター画面にリダイレクトして、各ベンダーに送信された注文を表示できます。 これらはエンドポイントと呼ばれ、Camelはhttps://camel.apache.org/message-endpointl[Message Endpoint] EIPパターンをサポートしています。 Camelエンドポイントについては、エンドポイントの章で後述します。
Camelは通常、https://servicemix.apache.org/[Apache ServiceMix]、https://activemq.apache.org/[Apache ActiveMQ]、およびhttps://cxf.apache.org/[Apache CXF]で使用されます。サービス指向アーキテクチャを実装します。
Apache Camel-機能
Apache Camelの概要を見たので、次にその機能を掘り下げて、Apache Camelが提供するものを見てみましょう。 Apache Camelは、さまざまなEIPの実装を本質的に提供するオープンソースのJavaフレームワークであることはすでにわかっています。 Camelは、非常に多様なトランスポートとAPIへの接続を提供することにより、統合を容易にします。 たとえば、JMSからJSON、JSONからJMS、HTTPからJMS、FTPからJMS、さらにHTTPからHTTP、マイクロサービスへの接続を簡単にルーティングできます。 単に両端に適切なエンドポイントを提供する必要があります。 Camelは拡張可能であるため、将来、より多くのエンドポイントをフレームワークに簡単に追加できます。
EIPとトランスポートを接続するには、Java、Scala、Groovyなどのドメイン固有言語(DSL)を使用します。 典型的なJavaルーティングルールは次のようになります-
from ("file:/order").to("jms:orderQueue");
このルーティングルールは、 order ディレクトリからファイルをロードし、ファイルの内容でJMSメッセージを作成し、そのメッセージを orderQueue というキューに送信します。
以下に、Camelアプリケーションの開発に役立つCamelの最も重要な機能をいくつか紹介します-
- Camelは、プラグイン可能なhttps://camel.apache.org/data-formatl[data]形式とそのようなメッセージ変換のための型コンバーターをサポートしているため、将来、新しい形式とコンバーターを追加できます。 現在、いくつかの一般的な形式とコンバータをサポートしています。いくつか例を挙げると、CSV、EDI、JAXB、JSON、XmlBeans、XStream、Flatpack、Zip。
- Camelは、DSLで述語を書き込むためのプラグイン可能なhttps://camel.apache.org/languagesl[languages]をサポートしています。 サポートされている言語には、JavaScript、Groovy、Python、PHP、Ruby、SQL、XPath、XQueryなどがあります。
- CamelはPOJOモデルをサポートしているため、さまざまな時点でJavabeansをプラグインできます。
- Camelは、メッセージングを使用することにより、このような大規模な分散システムおよび非同期システムのテストを容易にします。
Camelのアーキテクチャを理解し、さまざまな機能がどのように実装されているかを見てみましょう。
Apache Camel-アーキテクチャ
Camelアーキテクチャは、Integration EngineとRouter、Processors、およびComponentsの3つのコンポーネントで構成されています。 これは、次の図に示されています-
Camelコア自体は非常に小さく、13の必須コンポーネントが含まれています。 残りの80以上のコンポーネントはコアの外部にあります。 これは、展開先への依存度を低く維持するのに役立ち、将来的に拡張機能を促進します。 Components モジュールは、外部世界への Endpoint インターフェースを提供します。 エンドポイントは、前の章で見た file:/order や jms:orderQueue などのURIで指定されます。
*Processors* モジュールは、エンドポイント間でメッセージを操作および仲介するために使用されます。 前述のEIPは、このモジュールに実装されています。 現在、https://www.informit.com/store/enterprise-integration-patterns-designing-building-9780321200686 [EIP book]およびその他の有用な処理ユニットに記載されている40以上のパターンをサポートしています。
*Processor* および *Endpoints* は、DSLを使用して *Integration EngineおよびRouter* モジュールに接続されます。 これらを配線する際、フィルターを使用して、ユーザー定義の基準に基づいてメッセージをフィルター処理できます。 前に述べたように、これらのルールを作成するにはいくつかのオプションがあります。 これには、Java、Scala、Groovy、またはXMLを使用できます。
ここで、Camelの最も重要なコンポーネント、つまり CamelContext をコアと見なすことができます。
Apache Camel-CamelContext
*CamelContext* は、次の図に示すように、キャメルの他のすべてのサービスへのアクセスを提供します-
さまざまなサービスを見てみましょう。 Registry モジュールはデフォルトではJNDIレジストリであり、アプリケーションが使用するさまざまなJavabeanの名前を保持しています。 SpringでCamelを使用する場合、これはSpring ApplicationContext になります。 OSGIコンテナでCamelを使用する場合、これは* OSGIレジストリ*になります。 名前が示すように Type converters には、入力をある形式から別の形式に変換するさまざまなタイプのコンバーターが含まれています。 組み込みのタイプコンバーターを使用するか、独自の変換メカニズムを提供できます。 Components モジュールには、アプリケーションで使用されるコンポーネントが含まれています。 コンポーネントは、指定した classpath の自動検出によってロードされます。 OSGIコンテナの場合、これらは新しいバンドルがアクティブ化されるたびにロードされます。 前の章で*エンドポイント*と*ルート*について既に説明しました。 *データ形式*モジュールにはロードされたデータ形式が含まれ、最後に*言語*モジュールはロードされた言語を表します。
ここのコードスニペットは、Camelアプリケーションで CamelContext がどのように作成されるかを垣間見ることができます-
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
//Configure filters and routes
}
}
);
*DefaultCamelContext* クラスは、 *CamelContext* の具体的な実装を提供します。 *addRoutes* メソッドでは、 *RouteBuilder* の匿名インスタンスを作成します。 複数の *RouteBuilder* インスタンスを作成して、複数のルーティングを定義できます。 同じコンテキストの各ルートには一意のIDが必要です。 ルートは実行時に動的に追加できます。 以前に定義されたものと同じIDを持つルートは、古いルートを置き換えます。
*RouteBuilder* インスタンスの内部について説明します。
ルート
ルーターは、 from メッセージを to ロケーションに移動するためのルールを定義します。 RouteBuilder を使用して、Java DSLでルートを定義します。 ルートを作成するには、組み込みの RouteBuilder クラスを拡張します。 ルートは from エンドポイントで始まり、エンドポイントへの1つ以上で終わります。 2つの間に、処理ロジックを実装します。 単一の configure メソッド内で任意の数のルートを設定できます。
ルートの作成方法の典型的な例を次に示します-
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.to("stream:out");
}
}
*RouteBuilder* クラスのconfigureメソッドをオーバーライドし、ルーティングとフィルタリングのメカニズムを実装します。 現在のケースでは、エンドポイント *DistributeOrderDSL* から受信した入力を、エンドポイント *stream:out* で指定されたコンソールにリダイレクトします。
言語選択
異なる言語でルートを作成できます。 3つの異なる言語で同じルートがどのように定義されるかの例をいくつか示します-
Java DSL
from ("file:/order").to("jms:orderQueue");
Spring DSL
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
Scala DSL
from "file:/order" -> "jms:orderQueue"
フィルター
入力コンテンツの一部を選択するには、フィルターを使用します。 フィルターを設定するには、任意のhttps://camel.apache.org/predicatel[Predicate]実装を使用します。 フィルタリングされた入力は、目的の宛先エンドポイントに送信されます。 この例では、石鹸の注文をすべて除外して、石鹸の注文をまとめて石鹸サプライヤーに送信できるようにします。
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items"))
.to("stream:out");
この例では、フィルタリングに xpath 述語を使用しています。 あなたがフィルタリングにJavaクラスを使用したい場合は、次のコードを使用します-
from("direct:DistributeOrderDSL")
.filter()
.method(new Order(),"filter")
.to("stream:out");
*Order* は、独自のフィルタリングメカニズムを備えたカスタムJavaクラスです。
あなたはここのように単一のルーティングで複数の述語を組み合わせることができます-
from("direct:DistributeOrderDSL")
.choice()
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
.when(header("order").isEqualTo("milk"))
.to("direct:milk")
.otherwise()
.to("direct:d");
そのため、すべての「オイル」注文はオイルベンダーに、「ミルク」注文はミルクベンダーに、残りは共通プールに送られます。
カスタムプロセッサ
カスタム処理を使用することもできます。 以下の例では、 myCustomProcessor というカスタムプロセッサを作成し、ルートビルダーで使用しています。
Processor myCustomProcessor = new Processor() {
public void process(Exchange exchange) {
//implement your custom processing
}
};
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:DistributeOrderDSL")
.process(myProcessor);
}
};
カスタムプロセッサを選択およびフィルタリングとともに使用して、メディエーションおよびルーティングをより適切に制御できます-
from("direct:DistributeOrderDSL")
.filter(header("order").isEqualTo("milk"))
.process(myProcessor);
XMLを使う
必要に応じて、より大きなXMLでルートを定義できます。 次のXMLスニペットは、Spring XMLを介したいくつかのフィルタリングとともにルートを作成する方法を示しています-
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
ルートがどのように構築されるかを見てきたので、エンドポイントを作成するさまざまなテクニックを見ていきます。
Apache Camel-エンドポイント
統合コードでエンドポイントがどのように見えるかについて学びました。 file:/order、jms:orderQueue、direct:distributeOrderDSL など、これまで使用してきた式がエンドポイントです。 ご覧のとおり、これらはURI仕様の形式に従います。 このURIの評価中に、 CamelContext は Endpoint インスタンスを作成します。 DSLで*エンドポイント*の実装をインスタンス化する必要はありません。
以前の例を使用すると、Java DSLでエンドポイントをここで指定します-
from ("file:/order").to("jms:orderQueue");
そして、ここでの春に-
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
どちらの場合も、エンドポイントは定数文字列です。 場合によっては、実行時にこの文字列を作成することができます。 これを行うには、Java String フォーマッタメソッドを使用します。 Camelは、実行時にこれらのURI文字列を作成するための別の簡単なアプローチを提供します。 この目的のために、Camelは、ユーザー指定のパラメーターを持つ引数を受け入れる fromF および toF メソッドを提供します。 次のステートメントは、 toF メソッドの使用を示しています-
from("direct:distributeOrderDSL”).toF("file://%s?fileName=%s", path, name);
これらのメソッドにより、Java組み込みの String フォーマッターメソッドを使用する必要がなくなります。
Camelは、デフォルトでhttps://camel.apache.org/simplel[Simple]言語を使用してエンドポイント式を計算します。 Simple 言語は、 XPath の複雑さをあまり気にせずに、 Expressions および* Predicates を評価するために主に設計されました。 述語を評価するために、 *xpath などの別の言語をデフォルトの Simple 言語と組み合わせることができます。 これは、プラス記号を使用して他の言語を分離することにより行われます。 ここのコードスニペットは、 xpath 文字列を Simple で記述された式に連結する方法を示しています。
from("direct:start")
.toD("jms:${orderQueue}+language:xpath:/order/@id");
- 春*では、ここと同じことを達成できます-
<route>
<from uri = "direct:start"/>
<toD uri = "jms:${orderQueue}+language:xpath:/order/@id"/>
</route>
必要な数の言語を連結できます。各言語は、前の言語からプラス記号で区切られています。 サポートされている言語のリストは、https://camel.apache.org/languagesl [こちら]にあります。
Apache Camel-コンポーネント
Camelは、いくつかの事前に構築されたコンポーネントを提供します。
この章では、 camel-core モジュールのいくつかの重要なコンポーネントについて説明します。
Bean
*Bean* コンポーネントは、BeanをCamelメッセージ交換にバインドします。 エンドポイントを作成するURIは *bean:beanID* として指定されます。ここで、 *beanID* は *Registry* で指定されたBeanの名前です。
JndiContext jndiContext = new JndiContext();
jndiContext.bind("MilkOrder", new MilkOrderProcessor());
CamelContext camelContext = new DefaultCamelContext(jndiContext);
camelContext.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:bigBasket")
.to("bean:MilkOrder?method=placeOrder");
}
});
- bean:プロトコルを使用してエンドポイントを指定する方法に注意してください。 オプションで、呼び出すBeanメソッドを指定できます。この場合、エンドポイント式の評価中に *placeOrder というメソッドが呼び出されます。 MilkOrder は、コードスニペットの最初の2行で登録されている MilkOrderProcessor JavabeanのJNDI名です。 MilkOrderProcessor の定義自体は、簡潔にするためにここでは省略されています。
直接
前の例で Direct を使用していることに気付いたはずです。 石油ベンダーに注文を送信するために、エンドポイント仕様で direct:oil を使用しました。 Direct コンポーネントを使用すると、エンドポイントを同期的に呼び出すことができます。 前の例の次の2つのコードスニペットは、 Direct の使用を示しています-
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
And,
from("direct:DistributeOrderDSL")
.process(myProcessor);
File
*File* コンポーネントは、マシン上のファイルシステムへのアクセスを提供します。 このコンポーネントを使用すると、他のコンポーネントからのメッセージをローカルディスクに保存できます。 さらに、他のCamelコンポーネントがローカルファイルを処理できるようにします。 Fileコンポーネントの使用中に、URI形式として *file:directoryName [?options]* または *file://directoryName [?options]* を使用できます。 あなたは以前にこのコンポーネントの使用を見てきました-
from ("file:/order").to("jms:orderQueue");
*File* コンポーネントはデフォルトでディレクトリ名を取ることに注意してください。 したがって、注文ディレクトリのコンテンツは入力コンテンツとして使用されます。 *order* ディレクトリ内の特定のファイルを指定するには、次のステートメントを使用します-
from ("file:/order?fileName = order.xml").to("jms:orderQueue");
Log
*Log* コンポーネントを使用すると、基になるロギングメカニズムにメッセージを記録できます。 Camelは、さまざまなロギングフレームワークの抽象化として、Simple Logging Facade for Java(SLF4J)を使用します。 ロギングには *java.util.logging、logback、log4j* を使用できます。 このコードスニペットは、*ログ*コンポーネントの使用を示しています-
from("direct:DistributeOrderDSL")
.to("bean:MilkOrder?method = placeOrder")
.to("log:com.example.com?level = INFO&showBody = true");
SEDA
*SEDA* コンポーネントを使用すると、同じ *CamelContext* 内の別のエンドポイントを非同期に呼び出すことができます。 CamelContextインスタンス間で呼び出したい場合は、 *VM* コンポーネントを使用する必要があります。 SEDAの使用はここに示されています-
from("direct:DistributeOrderDSL")
//send it to the seda queue that is async
.to("seda:nextOrder")
このルートでは、注文を nextOrder 非同期キューにルーティングします。 このキューにサブスクライブしているクライアントは、このキューからメッセージを取得します。
タイマー
*Timer* コンポーネントは、定期的にメッセージを送信するために使用されるため、Camelアプリケーションのテスト中に非常に役立ちます。 ここのコードスニペットは、2秒ごとにコンソールにテストメッセージを送信します-
from("timer://testTimer?period = 2000")
.setBody()
.simple("This is a test message ${header.timer}")
.to("stream:out");
Apache Camel-メッセージキュー
ほとんどの統合プロジェクトは、疎結合アプリケーションアーキテクチャの作成に役立つため、メッセージングを使用します。 メッセージングは、同期または非同期のいずれかです。 JMSは point-to-point および publish-subscribe モデルの両方をサポートしています。 ポイントツーポイントには Queue を使用し、パブリッシュ/サブスクライブモデルには Topic を使用します。 Javaプラットフォームでは、JMS-Java Messaging Serviceはメッセージングサーバーへのインターフェースを提供します。 Apache activeMQは、そのようなオープンソースJMSプロバイダーの1つです。 CamelはJMSプロバイダーには付属していません。ただし、activeMQを使用するように構成できます。 このコンポーネントを使用するには、プロジェクトにactivemq、camel-spring、およびcamel-jmsのjarを含める必要があります。
次のコードスニペットは、activeMQ用にCamelを構成する方法を示しています。
<bean id = "jms" class = "org.apache.camel.component.jms.JmsComponent">
<property name = "connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name = "orderQueue" value = "tcp://localhost:61000"/>
</bean>
</property>
</bean>
ここで、Camelアプリケーションは orderQueue というキューのリッスンを開始します。 キュー自体は、ローカルホストで実行され、ポート61000にリストされているactiveMQメッセージングサーバーにセットアップされます。 これが完了すると、アプリケーションは、アプリケーションで定義されたエンドポイントのいずれかからこのキューにメッセージを送信または受信できます。
最後に、Camelアプリケーションがどのように作成されるかをより深く理解するために、すべてをプロジェクトにまとめるときが来ました。
Apache Camel-プロジェクト
Mavenを使用してCamelプロジェクトをビルドします。 ただし、開発にはIntelliJ IDEを使用することをお勧めします。 このプロジェクトには、任意のIDEを使用できます。
新しいプロジェクトの作成
新しい Maven プロジェクトを作成し、次を指定します-
GroupId: Basket
ArtifactId: Basket
プロジェクトのデフォルトの場所を選択するか、選択したディレクトリを指定します。
依存関係の追加
Camelを使用するには、いくつかの依存関係を追加する必要があります。 依存関係は pom.xml に追加されます。 だからpom.xmlを開き、次の2つの依存関係を追加します-
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
注-アプリケーションには最低限の依存関係が必要です。 ライブラリからより多くのCamelコンポーネントを使用する場合、対応する依存関係をこのpom.xmlファイルに追加する必要があります。
Java DSLの作成
次に、フィルタリングおよびルーティングコードをJava DSLで記述します。 DistributeOrderDSL という新しいJavaクラスを作成します。 それに次のコードを追加します-
public class DistributeOrderDSL {
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product='soaps']/items")).to("stream:out");
//.to("file:src/main/resources/order/");
}
});
context.start();
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
} finally {
context.stop();
}
}
}
*main* メソッドでは、最初に *DefaultCamelContext* クラスで提供されるデフォルトの実装をインスタンス化して *CamelContext* を作成します。
CamelContext context = new DefaultCamelContext();
次に、匿名 RouteBuilder インスタンスを作成してルートを追加します-
context.addRoutes(new RouteBuilder() {
*configure* メソッドをオーバーライドして、ルートを直接URI *DistributeOrderDSL* からシステムコンソールに追加します。 xpathクエリを使用してフィルタリングを提供します。
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items")).to("stream:out");
//.to("file:src/main/resources/order/");
}
ルートを追加した後、コンテキストを開始します-
context.start();
次に、直接URIを作成するためのコード- DistributeOrderDSL を追加します。
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
最後に、処理を開始します-
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
これで、Java DSLコードが完成したら、アプリケーションをテストする前に残っていることは、プロジェクトに order.xml ファイルを追加することだけです。 この目的のために、「はじめに」の章に示されているサンプルXMLを使用できます。
試験結果
あなたがアプリケーションを実行すると、次の出力が表示されます-
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
ここでは石鹸の注文のみがリストされていることに注意してください。 これをローカルファイルに保存する場合は、 stream.out 行をコメント化し、 configure メソッドで次の行のコメントを外します-
//.to("file:src/main/resources/order/");
次のセクションでは、CamelをSpringで使用する方法を学習します。
Apache Camel-Springでの使用
Springを使用して、前の章からアプリケーションを再作成します。 これにより、DSLではなくXMLでCamelルーティングを作成する方法がわかります。
新しいプロジェクトの作成
新しい Maven プロジェクトを作成し、次を指定します-
GroupId: BasketWithSpring
ArtifactId: BasketWithSpring
プロジェクトのデフォルトの場所を選択するか、選択したディレクトリを指定します。
依存関係の追加
以前のアプリケーションで使用したコア依存関係に加えて、Springを使用するためにいくつかの依存関係を追加する必要があります。 依存関係はpom.xmlに追加されます。 今、pom.xmlを開き、次の依存関係を追加します-
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.15.1</version>
</dependency>
</dependencies>
Spring用のJava DSLの作成
*DistributeOrderXML* という新しいJavaクラスを作成しましょう。 それに次のコードを追加します-
public class DistributeOrderXML {
public static void main(String[] args) throws Exception {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
try {
camelContext.start();
ProducerTemplate orderProducerTemplate = camelContext.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderXML", orderInputStream);
} finally {
camelContext.stop();
}
}
}
*main* メソッドでは、まず、 *ApplicationContext* のインスタンスを作成します。これは、Springアプリケーション内の中心的なインターフェイスです。 コンストラクターで、ルーティングおよびフィルター情報を含むXMLファイルの名前を指定します。
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
次に、上記で作成した ApplicationContext をパラメーターに指定して CamelContext を作成します。
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
この時点で、ルーティングとフィルタリングが設定されました。 したがって、 start メソッドを使用して CamelContext を開始します。 前の場合と同様に、order.xmlファイルをロードするためのエンドポイントを定義し、処理を開始します。 ここで、XMLでルーティングがどのように定義されるかを理解しましょう。
アプリケーションコンテキストの作成
プロジェクトに新しいXMLファイルを追加し、それを* SpringRouteContext.xml。*と呼びます。次の内容をこのファイルにカットアンドペーストします。
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd ">
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
</beans>
ここで、xpathクエリを次のように定義します。「オイル」のすべての注文を選択することに注意してください。
<xpath>//order[@product = 'Oil']/items</xpath>
出力エンドポイントは複数です。 最初のエンドポイントは order フォルダーを指定し、2番目のエンドポイントはコンソールを指定します。
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
アプリケーションを実行してください。
試験結果
アプリケーションを実行すると、画面に次の出力が表示されます。
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
指定したパスの order フォルダーをチェックアウトします。 上記のXMLコードを含む新しく作成されたファイルが見つかります。
結論
Camelは、EIPを実装してすぐに使用できるフレームワークを提供し、統合プロジェクトを容易にします。 ドメイン固有の言語でのコーディングとXMLの使用もサポートしています。