S-JIS[2011-12-06/2017-12-03] 変更履歴

Asakusa Framework バッチ引数渡し

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 CLIrunサブコマンドの場合も-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

バッチ引数を取得する例

Operator DSLでバッチ引数を取得する例

プログラム内からは、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でバッチ引数を取得する例

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


AsakusaFW目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま