Show page source of スタンドアロン版Camelの例 #78079

「ファイルを一方のフォルダから他方のフォルダにコピーする」サンプルを例にとり、色々な方法でやってみます。

[[Thumb(model.png, size=large, caption=送信元フォルダにあるファイルを送信先にコピーする)]]

= (その1)Javaで作成 =

以下のようなモデルをJavaで作成してみます。

[[Thumb(fileToFileJava.png, size=large, caption=Java版]]

Javaで書くと以下のようになります。

{{{ code 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を使う場合に比べ下記の問題があります。

 * フォルダが変更になったり、送信先が増えたり、プロトコルが変わったり(例えばFTP送信に変更)と、要件の変更/追加に伴いコードが読みにくくなる
 * プログラム起動時に送信元フォルダにあったファイルだけが処理される。このため1日に複数回送信元フォルダにファイルが置かれる場合、cron等を使って定期的にプログラムを起動する必要がある
 * エラーに対する処理が貧弱(というかない!)。またエラー以外にも様々なパターンを考慮したコードを追加する必要がある。
   * 例えばフォルダがない場合、同一ファイルが存在する場合、途中でシステムダウンした場合…などでも問題なく動作するようにする必要がる


= (その2)Camelで作成 =

続いてCamelを使って同じことをやってみます。ここではCamelのルーティング言語の一つであるJavaDSLを利用します。

[[Thumb(fileToFileCamel.png, size=large, caption=Camel版(JavaDSLでルーティングを記述)]]

=== メイン ===

最初にメインコード

{{{ code java
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();
	}
}
}}}

===  処理(ルーティング) ===

{{{
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}");
	}
}
}}}



= Camel+Springで作成 =

Springを使ってCamelを動作させることも可能。Springを使うことでトランザクションマネージャに参加することができる。SpringDSLをつかって記述してみる。

[[Thumb(fileToFileCamelSpring.png, size=large, caption=送信元フォルダにあるファイルを送信先にコピーする Camel+Spring版)]]

{{{ code java
public class Main {

	/**
	 * @param args
	 */
	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ファイルを置く。名前は任意。
{{{ code html
<?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&amp;delay=5000" />
			<to uri="file:/home/knoppix/Desktop/outbox?fileName=${file:name.noext}.${date:now:yyyyMMdd-HH:mm:ss}" />
		</route>
	</camelContext>
</beans>
}}}