サンプルコード (FileToFileのCamelサンプル) | 2012-03-13 17:34 |
documents (OSC2015沖縄セミナー資料) | 2015-07-09 11:48 |
「ファイルを一方のフォルダから他方のフォルダにコピーする」サンプルを例にとり、色々な方法でやってみます。
以下のようなモデルをJavaで作成してみます。
Javaで書くと以下のようになります。
- public class Main {
- public static void main(String args[]) throws Exception {
- File inboxDirectory = new File("/home/knoppix/Desktop/inbox");
- File outboxDirectory = new File("/home/knoppix/Desktop/outbox");
- outboxDirectory.mkdir();
- File[] files = inboxDirectory.listFiles();
- for (File source : files) {
- //出力ファイル名の拡張子を日付に変える
- Date date = new Date();
- SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd'-'HH'.'mm'.'ss");
- String[] strArray = source.getName().split("\\.");
- String destFileName ="";
- for(int i=0; i<strArray.length-1;i++){
- destFileName +=destFileName.concat(strArray[i]);
- }
- destFileName += destFileName.concat("." + sdf1.format(date));
- File dest = new File(outboxDirectory.getPath() + File.separator
- + destFileName);
- copyFile(source, dest);
- }
- }
- private static void copyFile(File source, File dest) throws IOException {
- OutputStream out = new FileOutputStream(dest);
- byte[] buffer = new byte[(int) source.length()];
- FileInputStream in = new FileInputStream(source);
- in.read(buffer);
- try {
- out.write(buffer);
- System.out.println("Copy from " +source.getAbsolutePath() + " To " + dest.getAbsoluteFile());
- } finally {
- out.close();
- in.close();
- }
- }
- }
Javaで処理を記述した場合、後述するCamelを使う場合に比べ下記の問題があります。
続いてCamelを使って同じことをやってみます。ここではCamelのルーティング言語の一つであるJavaDSLを利用します。
Camelの場合、「Aをする→Bをする→Cをする…」といったように、処理の流れをルートとして記述します。
つまり今回のようなファイルのコピー処理は「ファイルを取得する→ファイル名の拡張子を変更する→ファイルを出力する」というルートになりますが、Camelの便利な機能の一つとして「ファイルを出力する」機能の中でファイルの拡張子を変更できるので、今回はこれを使って実現します。
結局Camelでのルーティングは「ファイルを取得する→ファイル名を変えてファイルを出力する」というルーティング処理になります。
最初にメインコードを記述します。ここでやっていることのメイン処理は以下になります。
- import org.apache.camel.impl.DefaultCamelContext;
- public class Main {
- public static void main(String args[]) throws Exception {
- // 1:最初にCamelContextを作成する
- CamelContext context = new DefaultCamelContext();
- RouteBuilder routeBuilder = new FileToFileRoute();
- context.addRoutes(routeBuilder);
- // 2:作成したCamelContextを開始し、60秒後に停止
- context.start();
- Thread.sleep(60000);
- context.stop();
- }
- }
ルーティング部分はRouteBuilderを拡張し、実際の処理をルートとして記述します。
public class FileToFileRoute extends RouteBuilder { @Override public void configure() throws Exception { from("file:/home/knoppix/Desktop/inbox?noop=true&delay=5000") //noop=true:処理後、 //ファイルの削除をしない .to("file:/home/knoppix/Desktop/outbox?fileName=${file:name.noext}.${date:now:yyyyMMdd-HH:mm:ss}"); } }
ルーティングの記述はSpringでも記述できます。Springを使うことでトランザクションマネージャに参加が可能になります。それではルーティング部分をSpringDSLで記述してみます。
- public class Main {
- public static void main(String args[]) throws Exception {
- // ${CLASSPATH}/META-INF/spring/*.xmlファイルを探して実行する
- // ルーティングは${CLASSPATH}/META-INF/spring/myRoute.xmlで定義している
- System.out.println("デスクトップのinbox内ファイルを置くとoutboxにコピーされます。");
- System.out.println("DEBUGログはmylog.logを参照してください");
- System.out.println("Ctrl-Cで終了してください。");
- org.apache.camel.spring.Main.main(args);
- }
- }
クラスパスの通ったディレクトに"META-INF/spring"ディレクトリを作成し、そこにルーティング用の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-3.0.xsd
- http://camel.apache.org/schema/spring
- http://camel.apache.org/schema/spring/camel-spring.xsd">
- <!-- Camel Contextのコンフィギュレーション -->
- <camelContext xmlns="http://camel.apache.org/schema/spring">
- <route id="route_ファイル読み込んだ後に書込み">
- <from uri="file:/home/knoppix/Desktop/inbox?noop=true&delay=5000" />
- <to uri="file:/home/knoppix/Desktop/outbox?fileName=${file:name.noext}.${date:now:yyyyMMdd-HH:mm:ss}" />
- </route>
- </camelContext>
- </beans>
上記3つの例で示したように、同じことをやるのに様々な実現方法があります。CamelやCamel+Springでの記述は最初は分かりにくく感じるかもしれませんが、処理をルートとして記述する、という考え方なので、ルートの間に別の処理を挿入して機能の拡張が簡単にできます。また今回はファイルの読み書きにFileコンポーネントという部品を使いましたが、コンポーネントには多数のオプションがあり、役に立ちそうなオプションをコンポーネントにどんどん追加できます。