Весенняя партия двух ступеней с одним решателем - PullRequest
0 голосов
/ 17 сентября 2018

У меня следующая работа:

@Bean
fun createCsvJob(
    jobs: JobBuilderFactory,
    validateCsvHeaderStep: Step,
    processCsvStep: Step,
    moveCsvStep: Step,
    markCsvAsFailedStep: Step,
    moveFailedCsvStep: Step
) = jobs.get(PROCESS_CSV_JOB)
    .start(validateCsvHeaderStep)
    .next(processCsvStep)
    .on("*").to(decider())
    .from(decider()).on(ExitStatus.COMPLETED.exitCode).to(moveCsvStep)
    .from(decider()).on(ExitStatus.FAILED.exitCode).to(markCsvAsFailedStep).next(moveFailedCsvStep)
    .build()
    .build()!!

Есть два шага, которые могут завершиться ошибкой validateCsvHeaderStep и processCsvStep. Я хотел бы иметь поток, когда ошибка при обработке перейдет к markCsvAsFailedStep и moveFailedCsvStep, но когда все работает нормально, он должен перейти к moveCsvStep.

В настоящее время, если validateCsvHeaderStep терпит неудачу, вся работа терпит неудачу.

Когда я пытаюсь добавить decider, как это:

    .start(validateCsvHeaderStep)
    .on(ExitStatus.FAILED.exitCode).to(decider())
    .on(ExitStatus.COMPLETED.exitCode).to(processCsvStep)
    .on("*").to(decider())
    .from(decider()).on(ExitStatus.COMPLETED.exitCode).to(moveCsvStep)
    .from(decider()).on(ExitStatus.FAILED.exitCode).to(markCsvAsFailedStep).next(moveFailedCsvStep)

Я получаю:

Next state not found in flow=myJob for state=myJob.validateCsvStep with exit status=COMPLETED

Есть ли способ добиться обработки ошибок для обоих шагов без дублирования логики?

1 Ответ

0 голосов
/ 17 сентября 2018

Вам необходимо определить поток, начиная с validateCsvHeaderStep до решающего значения на COMPLETED следующим образом:

.start(validateCsvHeaderStep)
.on(ExitStatus.COMPLETED.exitCode).to(processCsvStep)
.from(validateCsvHeaderStep)on("*").to(decider())

вот два шага, которые могут не пройти validateCsvHeaderStep и processCsvStep. Я хотел бы иметь поток, когда ошибка при обработке перейдет к markCsvAsFailedStep и moveFailedCsvStep, но когда все работает нормально, он должен перейти к moveCsvStep.

Вот пример:

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public Step validateCsvHeaderStep() {
        return steps.get("validateCsvHeaderStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("validateCsvHeaderStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step processCsvStep() {
        return steps.get("processCsvStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("processCsvStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step markCsvAsFailedStep() {
        return steps.get("markCsvAsFailedStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("markCsvAsFailedStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step moveFailedCsvStep() {
        return steps.get("moveFailedCsvStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("moveFailedCsvStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step moveCsvStep() {
        return steps.get("moveCsvStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("moveCsvStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job() {

        return jobs.get("job")
                .flow(validateCsvHeaderStep())
                    .on(ExitStatus.FAILED.getExitCode()).to(markCsvAsFailedStep())
                    .from(validateCsvHeaderStep()).on("*").to(processCsvStep())

                    .from(processCsvStep()).on(ExitStatus.FAILED.getExitCode()).to(markCsvAsFailedStep())
                    .from(processCsvStep()).on("*").to(moveCsvStep())

                    .from(markCsvAsFailedStep()).on("*").to(moveFailedCsvStep())

                    .from(moveFailedCsvStep()).end()
                    .build();
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

печатает:

validateCsvHeaderStep
processCsvStep
moveCsvStep

Если, например, validateCsvHeaderStep не удалось:

    @Bean
    public Step validateCsvHeaderStep() {
        return steps.get("validateCsvHeaderStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("validateCsvHeaderStep");
                    chunkContext.getStepContext().getStepExecution().setExitStatus(ExitStatus.FAILED);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

Он печатает:

validateCsvHeaderStep
markCsvAsFailedStep
moveFailedCsvStep

Если processCsvStep не удалось:

    @Bean
    public Step processCsvStep() {
        return steps.get("processCsvStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("processCsvStep");
                    chunkContext.getStepContext().getStepExecution().setExitStatus(ExitStatus.FAILED);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

печатает:

validateCsvHeaderStep
processCsvStep
markCsvAsFailedStep
moveFailedCsvStep

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...