Asakusa Frameworkでバッチに引数を渡す方法のメモ。
|
|
Asakusa Frameworkでは、バッチの実行時(YAESS)に引数を渡し、プログラム(DSL)内から取得することが出来る。
プログラム内からバッチ引数を取得するには、コンテキストAPI(BatchContextクラス)を使用する。
バッチの引数は、YAESSのシェルに-Aを付けて記述する。[2012-01-07]
$ $ASAKUSA_HOME/yaess/bin/yaess-batch.sh WordCountBatch -A arg1=zzz -A arg2=hoge
AsakusaFW 0.10.0のAsakusa CLIのrunサブコマンドの場合も-Aを付けて記述する。[2017-12-03]
$ $ASAKUSA_HOME/bin/asakusa run WordCountBatch -A arg1=zzz -A arg2=hoge
AsakusaFW 0.2.3(YAESS登場以前)では、「mvn package」でAsakusaFWアプリをパッケージングすると、バッチを実行するexperimental.shが生成される。
このシェルでは、環境変数ASAKUSA_BATCH_ARGSでバッチの引数を指定することが出来る。
ASAKUSA_BATCH_ARGSには、「引数名=値」をカンマ区切りで複数指定することが出来る。
$ export ASAKUSA_BATCH_ARGS='arg1=zzz,arg2=hoge' $ cd 〜/WordCountBatch $ bin/experimental.sh
プログラム内からは、BatchContextクラスのstaticメソッドであるget()を使ってバッチ引数を取得する。
import com.asakusafw.runtime.core.BatchContext;
public abstract class WordCountOperator { @GroupSort public void split(@Key(group = {}) List<TextModel> textList, Result<WordModel> out) { String arg1 = BatchContext.get("arg1"); Report.info("arg1=" + arg1); String arg2 = BatchContext.get("arg2"); Report.info("arg2=" + arg2); 〜 } }
実行時にバッチ引数が指定されていない場合はnullが返る。
Importer/Exporterの一部のメソッドでは、${}
でバッチ引数を取得できる。[2017-06-04]
public class ErrorRecordToCsv extends AbstractErrorRecordCsvOutputDescription { @Override public String getBasePath() { return "result/error/${arg1}"; } @Override public String getResourcePattern() { return "${arg2}.csv"; } 〜 }
オペレーターやフロー(およびバッチ)のテスト実行時にバッチ引数を指定する例。
Operatorのテストでは、テスト用のオブジェクト(OperatorTestEnvironment)を生成してバッチ引数をセットする。
import org.junit.Rule; import com.asakusafw.testdriver.OperatorTestEnvironment;
public class WordCountOperatorTest { @Rule public OperatorTestEnvironment environment = new OperatorTestEnvironment(); @Test public void testSplit() { environment.setBatchArg("arg1", "test1"); environment.setBatchArg("arg2", "test2"); environment.reload(); WordCountOperatorImpl operator = new WordCountOperatorImpl(); 〜 } }
OperatorTestEnvironmentを定義しないと、以下のようなエラーが出る。[2013-12-07]
java.lang.IllegalStateException: BatchContext is not yet initialized (internal error) at com.asakusafw.runtime.core.BatchContext$1.initialValue(BatchContext.java:39) at com.asakusafw.runtime.core.BatchContext$1.initialValue(BatchContext.java:36) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:160) at java.lang.ThreadLocal.get(ThreadLocal.java:150) at com.asakusafw.runtime.core.BatchContext.get(BatchContext.java:67) at com.example.operator.CategorySummaryOperator.selectAvailableItem(CategorySummaryOperator.java:78) at com.example.operator.CategorySummaryOperatorTest.selectAvailableItem(CategorySummaryOperatorTest.java:50) 〜
environmentに値をセットした後、reload()しないとエラーになる。[/2013-12-07]
java.lang.AssertionError: configure()によって設定が書き換えられていますが、reload()されていないようです at com.asakusafw.testdriver.OperatorTestEnvironment.after(OperatorTestEnvironment.java:205) 〜
ジョブフローのテストとバッチのテストでは、testerにバッチ引数をセットするメソッドがあるので、それを使う。
@Test public void testDescribe() { JobFlowTester tester = new JobFlowTester(getClass()); tester.setBatchArg("arg1", "fff"); tester.setBatchArg("arg2", "zzz"); 〜 }
(testerにはreload()は無い)
AsakusaFW 0.5から、@Batchにバッチ引数の詳細を定義できるようになった。[2013-08-02]
import com.asakusafw.vocabulary.batch.Batch; import com.asakusafw.vocabulary.batch.Batch.Parameter;
@Batch( name = "example.summarizeSales", parameters = { @Parameter(key = "date", comment = "業務日付", pattern = "\\d{4}-\\d{2}-\\d{2}") } )
@Batch( name = "example", comment = "パラメーターのサンプル", parameters = { @Parameter(key = "arg1", comment = "引数1", required = true), @Parameter(key = "arg2", comment = "引数2", required = true) } )
keyがバッチ引数の名前。
requiredはその引数が必須かどうか。デフォルトはtrue(必須)。
patternは、受け入れ可能な値の形式を正規表現で記述する。デフォルトは「.*
」(何でも可)。