Не удается заставить работать условные потоки весенней партии
У меня возникли проблемы с получением условного потока пакетов spring для работы с помощью Java config. Образцы, которые я видел в образцах spring batch, или тестовом коде spring batch, или в переполнении стека, как правило, показывают условное состояние, когда один шаг должен быть выполнен при условии, или это последний шаг,или оба. Это не тот случай, который мне нужно решить.
В процедурном псевдокоде я хочу, чтобы он вел себя как
initStep()
if decision1()
subflow1()
middleStep()
if decision2()
subflow2()
lastStep()
Итак, subflow1 и 2 условны, но init, middle и last всегда выполнять. Вот мой разобранный тестовый кейс. В текущей конфигурации он просто завершает работу после выполнения subflow1.
public class FlowJobTest {
private JobBuilderFactory jobBuilderFactory;
private JobRepository jobRepository;
private JobExecution execution;
@BeforeMethod
public void setUp() throws Exception {
jobRepository = new MapJobRepositoryFactoryBean().getObject();
jobBuilderFactory = new JobBuilderFactory(jobRepository);
execution = jobRepository.createJobExecution("flow", new JobParameters());
}
@Test
public void figureOutFlowJobs() throws Exception {
JobExecutionDecider subflow1Decider = decider(true);
JobExecutionDecider subflow2Decider = decider(false);
Flow subflow1 = new FlowBuilder<Flow>("subflow-1").start(echo("subflow-1-Step-1")).next(echo("subflow-1-Step-2")).end();
Flow subflow2 = new FlowBuilder<Flow>("subflow-2").start(echo("subflow-2-Step-1")).next(echo("subflow-2-Step-2")).end();
Job job = jobBuilderFactory.get("testJob")
.start(echo("init"))
.next(subflow1Decider)
.on("YES").to(subflow1)
.from(subflow1Decider)
.on("*").to(echo("middle"))
.next(subflow2Decider)
.on("YES").to(subflow2)
.from(subflow2Decider)
.on("*").to(echo("last"))
.next(echo("last"))
.build().preventRestart().build();
job.execute(execution);
assertEquals(execution.getStatus(), BatchStatus.COMPLETED);
assertEquals(execution.getStepExecutions().size(), 5);
}
private Step echo(String stepName) {
return new AbstractStep() {
{
setName(stepName);
setJobRepository(jobRepository);
}
@Override
protected void doExecute(StepExecution stepExecution) throws Exception {
System.out.println("step: " + stepName);
stepExecution.upgradeStatus(BatchStatus.COMPLETED);
stepExecution.setExitStatus(ExitStatus.COMPLETED);
jobRepository.update(stepExecution);
}
};
}
private JobExecutionDecider decider(boolean decision) {
return (jobExecution, stepExecution) -> new FlowExecutionStatus(decision ? "YES" : "NO");
}
}
2 ответа:
Ваше первоначальное определение работы также должно работать с небольшой поправкой. Тест был неудачным, потому что задание завершено (со статусом завершено) после первого субпотока. Если вы проинструктируете его перейти к среднему шагу, он должен работать так, как задумано. Аналогичная регулировка для второго потока.
Job job = jobBuilderFactory.get("testJob") .start(echo("init")) .next(subflow1Decider) .on("YES").to(subflow1).next(echo("middle")) .from(subflow1Decider) .on("*").to(echo("middle")) .next(subflow2Decider) .on("YES").to(subflow2).next(echo("last")) .from(subflow2Decider) .on("*").to(echo("last")) .build().preventRestart().build();
Подход, который я использовал для этой работы, состоял в том, чтобы разбить мои условные потоки на этапы потока.
public void figureOutFlowJobsWithFlowStep(boolean decider1, boolean decider2, int expectedSteps) throws Exception { JobExecutionDecider subflow1Decider = decider(decider1); JobExecutionDecider subflow2Decider = decider(decider2); Flow subFlow1 = new FlowBuilder<Flow>("sub-1") .start(subflow1Decider) .on("YES") .to(echo("sub-1-1")).next(echo("sub-1-2")) .from(subflow1Decider) .on("*").end() .end(); Flow subFlow2 = new FlowBuilder<Flow>("sub-2") .start(subflow2Decider) .on("YES").to(echo("sub-2-1")).next(echo("sub-2-2")) .from(subflow2Decider) .on("*").end() .end(); Step subFlowStep1 = new StepBuilder("sub1step").flow(subFlow1).repository(jobRepository).build(); Step subFlowStep2 = new StepBuilder("sub2step").flow(subFlow2).repository(jobRepository).build(); Job job = jobBuilderFactory.get("testJob") .start(echo("init")) .next(subFlowStep1) .next(echo("middle")) .next(subFlowStep2) .next(echo("last")) .preventRestart().build(); job.execute(execution); assertEquals(execution.getStatus(), BatchStatus.COMPLETED); assertEquals(execution.getStepExecutions().size(), expectedSteps); }