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は、受け入れ可能な値の形式を正規表現で記述する。デフォルトは「.*」(何でも可)。