Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
233
Help us understand the problem. What is going on with this article?
@daikuro

Apache Camel (Java)を使うと開発が楽になる7つの理由

More than 5 years have passed since last update.

まず本題に入る前に、ApacheCamelの簡単な説明から

Apache Camelとは

Javaのフレームワーク。どんなフレームワークかというと

  • ベルトコンベア(ライン生産的な)フレームワーク
  • 「生産物」に相当するものはデータ
  • 「生産物を作るロボットや人」に相当するものはコンポーネントや個別実装
  • 「スタート」は外部からのリクエストやタイマーでの監視(例えばメールチェックみたいな)
  • 「最終生成物」はリクエストもらった人に返す
  • フレームワーク自体は超軽量。

概要すぎるので、もうちょっと細かな話をすると

データ

  • エクスチェンジと呼ばれる「箱」でベルトコンベアに流れている
  • 箱の中にはメッセージと呼ばれる生産物が入っている
  • 箱の中にはメッセージの他に「エラー」やIDや処理過程の「パンくずリスト」なども入っている
  • メッセージの中はヘッダーボディがあって、ヘッダーがMap型、ボディがObject型になっている。メインとなるデータはボディで作って、サブ的なデータはヘッダーにどんどん入れていく使い方。
  • 例えばファイルでいうと、ファイルの中身がボディ、ファイ名やサイズ、日付等がヘッダーといった感じ。
  • Camelではベルトコンベアの事をルートと呼んでいる

コンポーネントや個別実装

<動作内容>
1. ベルトコンベアから箱をもらうので、中身を取り出す
2. 内容を見て処理をする
3. 処理した結果を箱に入れる

  • コンポーネントは色々準備されていて、外部システム接続の部分だったり、データ変換だったりが100種類以上用意されている。
  • コンポーネントは独自な実装というよりも、外部のよく使われているOSSライブラリのラッパーになっている
  • 既存のコンポーネントに頼らずとも、もちろん独自に自分で実装もできる。

外部からのリクエストやタイマー

  • HTTPリクエストなどを受信
  • その他のプログラムからのリクエストを受け取る
  • タイマーは1秒間隔だったり、毎週月曜だったり
  • ファイルコンポーネントをスタートに配置すると、毎秒指定のディレクトリをチェックして、新規ファイルがあったら読み込むといった処理になる

もっと細かな説明やサンプルは別の機会に書くことにして、理由のほうを。

理由1 > 既存コンポーネントが便利

  • ファイルを出力するコンポーネントをルートに配置して、ヘッダーにファイル名、ボディに内容を入れて渡すとファイルを生成してくれるといった感じ。
  • メールコンポーネントはメールを送ってくれる
  • Execコンポーネントはシェルやバッチファイルを起動してくれ、結果をボディにつめてルートに戻してくれる
  • コンポーネントを使うと個別のライブラリの使用方法をいちいち勉強しなくてもすむ
  • コンポーネントは全部で http://camel.apache.org/components.htmlhttp://camel.apache.org/data-format.html の2ページ。
  • コンポーネントもシンプルな作りなので、機能が足りなかったりしても自分でextendして機能を継ぎ足せる。

理由2 > どこでも動く

  • JavaVMのみでも
  • Tomcatでも
  • GoogleAppEnginでも
  • JBossでも
  • Groovyでも
  • JUnitでも
  • Jenkinsでも

軽量ライブラリだから環境選ばない。
軽量ライブラリだから、コンポーネントだけを使うという方法もできるんだけど、それは別の機会に説明。

理由3 > コードが読みやすくなる

  • コードの大きな流れを読むにはルート(ベルトコンベア)を見ればいいだけ
  • やりたい事を順にルートに並べていく
  • 細かな処理はルートから呼び出す処理に書ける
  • いろんな所に変数が散らばらない。すべての情報はエクスチェンジに入れるだけ。
  • 設計もいたって簡単になって、メインはデータ部分とベルトコンベアでの機能分割になると思う。
  • クラス変換が便利。クラスキャストのノリでクラス変換(データマッピング)ができる。

理由4 > デバッグがしやすい

  • エクスチェンジという箱の中身を見ると全部の処理中のデータが詰まっている。
  • つまりエクスチェンジをログ出力すると、処理中のデータがすべて見える。
  • エラーが発生するとスタックトレースとパンくずリスト(ベルトコンベア上でどの処理を通ったか)やエクスチェンジの内容全部がログに出力される
  • 試験コードが書きやすい。できていない処理を飛ばしてデータを流す事もできる。どう書けばいいかは、また別の機会。

理由5 > 複数人数で開発・分業しやすい

  • ベルトコンベア式だから、これができないとだねぇ。
  • どの処理でもエクスチェンジという同じ箱を使うので、前の処理が完成していなくても実装可能。
  • 処理単体での試験もできる。(想定データをエクスチェンジに詰めて投げるだけ)

理由6 > 意外としっかりした作り

  • 軽量なフレームワークなので、逆に機能不足かと思いきや・・・
  • EIPとか呼ばれる(https://www.graffletopia.com/stencils/137) 処理フローパターンを網羅するように意識して実装されている
  • 例外ハンドラ、トランザクション制御、リトライ制御、グレースフルな停止(処理中のデータが処理完了するまで待つ)、処理回数や時間などの統計などなど。
  • エラーになった処理(例えば外部にhttpリクエスト)を飛ばして後続の処理に進むという強制続行的なハンドリングすることもできる。

理由7 > ネタ的に

  • ルートはワンライナーで書けちゃう。

サンプル

HelloWorldなサンプルぐらい1個つけておかないと実感もできないのでちょっとだけ。
ルート(ベルトコンベア部分)は下記のようになる。

from("jetty:http://0.0.0.0:8081/api")
.to("sql:SELECT * FROM students WHERE id = :#id")
.marshal().json(JsonLibrary.Gson)
.to("log:resultMessage");

これを起動するとwebサーバ的な動作するので、次のようにアクセスすると
http://localhost:8081/api?id=1234
sqlが実行されて、結果のレコードがjson形式で結果として戻ってくる。
ログには結果データが吐出される。
といった感じ。

すべて既存コンポーネントをつなげただけで完成したので、独自実装が入ってない。
SQLの設定部分が書いてないのでこのままだと動かないけど、全体は次回にでも。

233
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
daikuro

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
233
Help us understand the problem. What is going on with this article?