[SpringBatch 실습] 8. JobRepository 를 사용하여 특정 JobName, JobParameters 에 해당하는 최신에 수행된 Job 정보 가져오기

반응형
728x90
반응형

Listner 생성 및 설정

JobRepositoryListener.java
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.*;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Slf4j
public class JobRepositoryListener implements JobExecutionListener {
    private final JobRepository jobRepository;

    @Override
    public void beforeJob(JobExecution jobExecution) {

    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        String jobName = jobExecution.getJobInstance().getJobName();

        // 실제로 저장된 데이터로 셋팅
        // BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("requestDate", "20220526").toJobParameters();

        // jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
        JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);

        if (lastJobExecution != null) {
            for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
                BatchStatus status = stepExecution.getStatus();
                ExitStatus exitStatus = stepExecution.getExitStatus();

                log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);

                String stepName = stepExecution.getStepName();

                log.info("stepName : {}", stepName);
            }
        }
    }
}

1) JobParameters 객체 생성하기

// 실제로 저장된 데이터로 셋팅
// BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
JobParameters jobParameters = new JobParametersBuilder()
        .addString("requestDate", "20220526").toJobParameters();

 

2) JobRepository 로 가장 마지막에 실행된 JobExecution 가져오기

// jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);

 

3) JobExecution 에서 StepExecution 여러개를 가져온다.

if (lastJobExecution != null) {
    for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
        BatchStatus status = stepExecution.getStatus();
        ExitStatus exitStatus = stepExecution.getExitStatus();

        log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);

        String stepName = stepExecution.getStepName();

        log.info("stepName : {}", stepName);
    }
}

 

  • JobExecution.getStepExecutions() 내부 로직
public Collection<StepExecution> getStepExecutions() {
   return Collections.unmodifiableList(new ArrayList<>(stepExecutions));
}

 

 

Job 생성

JobRepositoryConfiguration.java
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*
--job.name=jobRepositoryTestJob
 */

/**
 * SimpleStepHandler.java
 * AbstractStep.java
 * TaskletStep.java
 */
@Configuration
@RequiredArgsConstructor
public class JobRepositoryConfiguration {

    // job 생성
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    // listener
    private final JobRepositoryListener jobRepositoryListener;

    @Bean
    public Job jobRepositoryTestJob() {
        return this.jobBuilderFactory.get("jobRepositoryTestJob")
                .start(jobRepositoryStep1())
                .next(jobRepositoryStep2())
                .listener(jobRepositoryListener) // 리스너 적용
                .build();
    }

    @Bean
    public Step jobRepositoryStep1() {
        return stepBuilderFactory.get("jobRepositoryStep1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("jobRepositoryStep1");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step jobRepositoryStep2() {
        return stepBuilderFactory.get("jobRepositoryStep2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("jobRepositoryStep2");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}

1) 리스너 설정

@Bean
public Job jobRepositoryTestJob() {
    return this.jobBuilderFactory.get("jobRepositoryTestJob")
            .start(jobRepositoryStep1())
            .next(jobRepositoryStep2())
            .listener(jobRepositoryListener) // 리스너 적용
            .build();
}

 

 

배치 실행

program-arguments

--job.name=jobRepositoryTestJob requestDate=20220526

 

디버깅

if (lastJobExecution != null) {
    for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
        BatchStatus status = stepExecution.getStatus();
        ExitStatus exitStatus = stepExecution.getExitStatus();

        log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);

        String stepName = stepExecution.getStepName();

        log.info("stepName : {}", stepName);
    }
}

 

 

결과
jobRepositoryStep1
jobRepositoryStep2

BatchStatus : COMPLETED, ExitStatus : exitCode=COMPLETED;exitDescription=
stepName : jobRepositoryStep1

BatchStatus : COMPLETED, ExitStatus : exitCode=COMPLETED;exitDescription=
stepName : jobRepositoryStep2

 

 

 

배치 재수행

이제 배치를 재수행해보자.

 

program-arguments

--job.name=jobRepositoryTestJob requestDate=20220527

 

디버깅

@Override
public void afterJob(JobExecution jobExecution) {
    String jobName = jobExecution.getJobInstance().getJobName();

    // 실제로 저장된 데이터로 셋팅
    // BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
    JobParameters jobParameters = new JobParametersBuilder()
            .addString("requestDate", "20220526").toJobParameters();

    // jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
    JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);

    if (lastJobExecution != null) {
        for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
            BatchStatus status = stepExecution.getStatus();
            ExitStatus exitStatus = stepExecution.getExitStatus();

            log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);

            String stepName = stepExecution.getStepName();

            log.info("stepName : {}", stepName);
        }
    }
}

1) 현재 실행중인 JobExecution

 

2) 위 코드의 lastJobExecution

 

결론

20220526 파라미터에 해당하는 Job 중 가장 최신의 JobExecution을 가져온다.

 

 

 

 

반응형

Designed by JB FACTORY