Apache Camelでの実装イメージ
この"処理
"を実装する
- 処理は分担して実装できる
- 処理は何かのメッセージを受けて、何かのメッセージを返すだけ。
- 前の処理や後の処理の依存度が低ければ、処理の入れ替えや修正が簡単になる。
メッセージの形式
メッセージには下記の情報が含まれている。
処理はこの情報にデータ出し入れするだけ。
- Header (Map)
- Property (Map)
- Body (Object)
- Attachement
処理
処理の中では前の処理を考えずに、どういう型が欲しいかを書いてデータを取得する。
単なるキャストだけではなく、データ変換も行える
例えば、BodyからString形式で情報を取得したい場合は下記のように書く。
String body = exchange.getIn().getBody(String.class);
この時、メッセージの内容がIntegerでもFloatでもFileでもxmlでもInputStreamでも、Camelが自動的に変換してString形式にしてくれる。
(変換できなかったら type converterが見つかりません
みたいなエラーが出る。)
Headerの場合は
String header = exchange.getIn().getHeader("headerName", String.class);
この仕組を使って
from("file:test")
.to("http:xxxxxx");
と実装すると、フォルダを監視して、ファイルを発見するとFileインスタンスでメッセージを流して、そのあとhttpでファイルの内容を送信する事ができる
この例では、
* ファイル処理の実装は「ファイルを読み込んでメッセージに詰め込む」だけで、後の処理に何が入るかを考えていない。
* http送信処理の実装は「メッセージを読み込んで内容を送信する」だけで、手前の処理がファイル処理だろうが、FTP処理だろうかは考えていない。
独自のデータ変換登録
前の例ではCamelがデフォルトで持っているデータ変換処理を使ってデータを変換しているが、デフォルトで実装しているデータ変換で間に合わない場合はもちろんエラーになる。
たとえば、Mapをbyte[ ]に変換する場合は一律Json形式にすると決めたら下記のクラスを置いておけばいいだけ。
これで、この変換が必要な場合にCamelが呼び出す。
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.camel.Converter;
import java.io.UnsupportedEncodingException;
import java.util.Map;
@Converter
public class MapConverter {
@Converter
public static byte[] toByteArray(Map map) throws JsonProcessingException, UnsupportedEncodingException {
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(data);
return json.getBytes("utf-8");
}
}
@Converter
に関して、どこに置いても反応してくれるかどうかはドキュメントに書いてあるのかも。。。
私は同一プロジェクトの別パッケージ内にクラスを置いたけど動作していた。
参考
http://camel.apache.org/type-converter.html
このクラスを置いておくだけで、下の例のようなMapをhttpで送信する時には自動的にjsonに変換して送信してくれる
例:
.......
.process(exchange -> {
Map map = new HashMap();
map.put("aaa", 111);
map.put("bbb", 222);
exchange.getIn().setBody(map);
})
.to("http:....")
明示的に型変換をする場合
from("file:xxx")
.convertBodyTo(String.class)
だったり
from("file:xxx")
.process(exchange -> {
String body = exchange.getIn().getBody(String.class);
exchange.getIn().setBody(body);
})
javaオブジェクト --> json
from("xxxxxxxx")
.marshal().json(JsonLibrary.Jackson)
.to("yyyyy")
json --> javaオブジェクト
from("xxxxxxxx")
.unmarshal().json(JsonLibrary.Jackson)
.to("yyyyy")