JSR 352 Batch API で次のロジックを実現する方法はありますか? ジョブの開始時にわかっているさまざまな条件に基づいて、それぞれを実行する必要がある一連のステップがあります。ConditionsEntity は、外部システムによって提供されます。
public List<Steps> createStepSequence(ConditionsEntity conditions) {
if (conditions.isStep1Enabled()) {
steps.add(step1)
}
if (conditions.isStep2Enabled()) {
steps.add(step2)
}
if (conditions.isStep3Enabled()) {
steps.add(step3)
}
//many more ifs
return steps;
}
com.ibm.jbatch.container.exception.BatchContainerRuntimeException: 決定は別の決定より前に行うことはできません。ここにFAILINGコードを追加しています
<?xml version="1.0" encoding="UTF-8"?>
<job id="myJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd" version="1.0">
<properties>
<property name="isExecuteStep2" value="false"/>
<property name="isExecuteStep3" value="false"/>
</properties>
<step id="step1" next="decider1">
<batchlet ref="myBatchlet1"/>
</step>
<decision id="decider1" ref="SkipNextStepDecider">
<properties>
<property name="isExecuteNextStep" value="#{jobProperties['isExecuteStep2']}"/>
</properties>
<next on="EXECUTE" to="step2"/>
<next on="SKIP" to="decider2"/>
</decision>
<step id="step2">
<batchlet ref="myBatchlet2"/>
</step>
<decision id="decider2" ref="SkipNextStepDecider">
<properties>
<property name="isExecuteNextStep" value="#{jobProperties['isExecuteStep3']}"/>
</properties>
<next on="EXECUTE" to="step3"/>
<end on="SKIP"/>
</decision>
<step id="step3">
<batchlet ref="myBatchlet3"/>
</step>
</job>
@Named
public class SkipNextStepDecider implements Decider {
@Inject
@BatchProperty
private String isExecuteNextStep;
@Override
public String decide(StepExecution[] ses) throws Exception {
if (isExecuteNextStep.equalsIgnoreCase("true")) {
return "EXECUTE";
} else {
return "SKIP";
}
}
}
更新 passThroughStep を使用して、次の提案されたソリューションを実装しました。正しく動作していますが、このコードの重複をすべて回避できるようにしたいと思っています。
<?xml version="1.0" encoding="UTF-8"?>
<job id="decisionpoc" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="dummy0" next="decider1">
<batchlet ref="dummyBatchlet"/>
</step>
<decision id="decider1" ref="skipNextStepDecider">
<properties>
<property name="condition" value="isExecuteStep1"/>
</properties>
<next on="EXECUTE" to="step1"/>
<next on="SKIP" to="dummy1"/>
</decision>
<step id="step1" next="decider2">
<batchlet ref="myBatchlet1"/>
</step>
<step id="dummy1" next="decider2">
<batchlet ref="dummyBatchlet"/>
</step>
<decision id="decider2" ref="skipNextStepDecider">
<properties>
<property name="condition" value="isExecuteStep2"/>
</properties>
<next on="EXECUTE" to="step2"/>
<next on="SKIP" to="dummy2"/>
</decision>
<step id="step2">
<batchlet ref="myBatchlet2"/>
</step>
<step id="dummy2" next="decider3">
<batchlet ref="dummyBatchlet"/>
</step>
<decision id="decider3" ref="skipNextStepDecider">
<properties>
<property name="condition" value="isExecuteStep3"/>
</properties>
<next on="EXECUTE" to="step3"/>
<end on="SKIP"/>
</decision>
<step id="step3">
<batchlet ref="myBatchlet3"/>
</step>
</job>
決定者
@Named
public class SkipNextStepDecider implements Decider {
@Inject
@BatchProperty
private String condition;
@Inject
private JobContext jobContext;
@Override
public String decide(StepExecution[] ses) throws Exception {
Properties parameters = getParameters();
String isExecuteNextStep = parameters.getProperty(condition);
if (isExecuteNextStep.equalsIgnoreCase("true")) {
return "EXECUTE";
} else {
return "SKIP";
}
}
private Properties getParameters() {
JobOperator operator = getJobOperator();
return operator.getParameters(jobContext.getExecutionId());
}
}
私のテスト
public class DecisionPOCTest extends AbstractBatchLOT {
@Test
public void testProcess() throws Exception {
JobOperator jobOperator = getJobOperator();
Properties properties = new Properties();
properties.setProperty("isExecuteStep1", "true");
properties.setProperty("isExecuteStep2", "false");
properties.setProperty("isExecuteStep3", "true");
Long executionId = jobOperator.start("poc/decisionPOC", properties);
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
List<String> executedSteps = new ArrayList<>();
for (StepExecution stepExecution : stepExecutions) {
executedSteps.add(stepExecution.getStepName());
}
assertEquals(COMPLETED, jobExecution.getBatchStatus());
assertEquals(4, stepExecutions.size());
assertArrayEquals(new String[]{"dummy0", "step1", "dummy2", "step3"}, executedSteps.toArray());
assertFalse(executedSteps.contains("step2"));
}
}