1
votes

I'm using Spring batch for our batch processing, before I do batch processing I would like to do validate all job params like productName, productID, start date, end date, productType, if these Job params are null or contains bad value I have to fail the validation step and make the job failed.

I've written validation step and Tasklet, in my Tasklet I'm planning to handle the job param validation (to do null check for all the job param). Since I'm doing first time Spring batch I would like to hear from the expert is this right place to handle the job param validation or is there any efficient way of doing it. It would be really helpful if someone can help me to provide your valuable suggestion or example.

Appreciated your help in advance! Thanks

Please find my sample code below:

MyJobConfig.java

@Configuration
public class MyJobConfig {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean("myBatchJob")
    public Job job(@Qualifier("validateProductJobParam") Step validateProductJobParametersStep) {
        Job job = jobBuilderFactory.get("myBatchJob")
                .incrementer(new RunIdIncrementer())
                .start(validateProductJobParametersStep)
                .on("FAILED")
                .end()
                .from(validateProductJobParametersStep).on("*").to(processProductBatch)
                .end()
                .build();
        return job;
    }

    @Bean(name = "validateProductJobParam")
    public Step validateProductJobParametersStep() {
        return stepBuilderFactory.get("validate-product-param")
                .tasklet(new JobParamValidateTasklet())
                .allowStartIfComplete(true)
                .build();
    }

}

JobParamValidateTasklet.java

import org.springframework.batch.core.*;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

import java.util.Map;

public class JobParamValidateTasklet implements Tasklet, StepExecutionListener {

    private StepExecution stepExecution;
    private JobExecution jobExecution;
    private bookean isValidation;

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
        this.jobExecution = stepExecution.getJobExecution();

    }

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {

        Map<String,JobParameter> jobMap = jobExecution.getJobParameters().getParameters();

        String productName = (String)jobMap.get("PRODUCT_NAME").getValue();
        String productId = (String)jobMap.get("PRODUCT_ID").getValue();
        String prdouctType = (String)jobMap.get("PRODUCT_TYPE").getValue();

        if (productName == null &&  productId == null && prdouctType == null ) {
            isValidation = false;
        } else {
        isValidation = true;
        }
        
        return null;
    }

    public ExitStatus afterStep(StepExecution stepExecution) {
        if(!isValidation)
            return ExitStatus.FAILED;
        else
            return ExitStatus.COMPLETED;
    }

}
1

1 Answers

0
votes

Spring batch will use JobParametersValidator before every job execution. You don’t need to call it manually, but have to register it in your job definition and it gets called automatically. By default DefaultJobParametersValidator will be used if no custom validator is specified.

You can use https://docs.spring.io/spring-batch/docs/4.3.x/reference/html/job.html#jobparametersvalidator documentation for reference it shows how’s to register a validator.

update your MyJobConfig.class as below:

@Bean("myBatchJob")
public Job job(@Qualifier("validateProductJobParam") Step validateProductJobParametersStep) {
    Job job = jobBuilderFactory.get("myBatchJob")
            .incrementer(new RunIdIncrementer()).validator(validate())
            .start(processProductBatch)
            .end()
            .build();
    return job;
}

//implementation of validation

@Bean
public JobParametersValidator validate() {
    JobParametersValidator j = new JobParametersValidator() {
        
        @Override
        public void validate(JobParameters jparams) throws JobParametersInvalidException {
            Map<String, JobParameter> params = jparams.getParameters();
            if(null == params.get("PRODUCT_NAME").getValue() || null == params.get("PRODUCT_ID").getValue()
                    || null == params.get("PRODUCT_TYPE").getValue()){
                throw new JobParametersInvalidException("Cant be null");
            }
        }
    };
    return j;       
}